Documentation
Download Latest Version Index JumpStart FAQ History
CapeSoft Logo

CapeSoft Secwin
Documentation

Installed Version Latest Version GOLD


What's new in Secwin 6?

Things you absolutely have to know before you start

Take a couple of minutes to read this section. It may cover some terms and ideas you already know, but it will save much frustration and heartache later.

Secwin is a mature Feature-Rich package. This means that the most common problem encountered by new users is Feature Overload. With so many features, and possibilities, it's hard to understand how to accomplish the simple tasks. Of course the features are there for a reason, and you'll appreciate them later, but for now they get in the way.

One way to overcome this problem is to check out the JumpStart section for task orientated documentation. For example you just want to add the Login features? No problem, check out the section on Adding Logins and Passwords. Just want to implement product Registration? Check out the Adding Licensing and Registration Features. (Not yet though read the rest of this section first!)

Secwin is divided into 2 halves. You can use either half separately, or the two together in an integrated system.
Secwin also makes extensive use of Templates in order to implement the features that you want. If you've been using Clarion for a while then you're already familiar with the power that templates offer. But if you haven't used a 3rd party template before then take a moment to read the QuickStart section entitled Using templates in Clarion. Secwin uses a mixture of Extension/Control and Code templates.

If you are supplying a program which needs translation then read the section entitled Translating Secwin Windows.

Secwin stores the security settings in a file called dssw5.TPS. This contains both the Access Control settings and the Licensing settings. Please note that in the case of the 30 day demo licensing feature, deleting the dssw5.TPS file does not allow you to get another 30 day license. For more information on this feature see the 30 Day Demo section in the Secwin User Guide.

Although Secwin contains a feature called Super Users, this is not a security back door. For a full explanation of the Super User features see the section in the User Guide called Super Users.

Important Note: The security files are not encrypted. The sensitive fields are encrypted, so that security is not an issue, but illegal write activity is possible. Secwin will detect when an illegal write activity has been made  to the security files, and will not allow the user to run the application. You need to keep regular backups so that the user can immediately roll back to a previous version of the security files and continue running your application.

[Each developer needs his own license to use Secwin. (Need to buy more licenses?) ]

Features included in Secwin 6

What must I change in my app when I upgrade from Secwin 3/4 to Secwin 6?
How do I upgrade from Secwin 3/4 to Secwin 6?
Why is CapeSoft charging for an upgrade from Secwin 3/4 to Secwin 6?

Features included in Secwin 4: (This is old news now, but for reference for folk upgrading from Secwin 3)

Access Control: Licencing and Registration Control: Additional Features: Note: in Secwin 6, all the File driver DLLs are included in the main install, so you will not require any additional install files for other driver support.

What do we need to change in order to upgrade from Secwin 3 to Secwin 4?


JumpStart: Adding the Licensing and Registration Features

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.

  1. Add Secwin's Activate Security Global extension to your Application.
    In the following template prompts of the Global Extension Template:
    a) Enter Unique Application Name.
    b) On the Licensing tab, uncheck the Disable Licensing support and enter the License Name and Seed Code. These should be unique for your app, but remember them we'll use them again later. You can ignore the other template prompts, these are superfluous at this stage.
    c) On the Files tab set the Allow Program to create Security Files on, and set the Position to Exe directory. If your application uses SQL, then see the Secwin Global Extension template for details on setting up an SQL connection for the Secwin tables. You can ignore the other template prompts, these are superfluous at this stage.
  2. In the Template utility item on the Application menu, Run the Template utility: CreateMyRegisterProductWindow. This will add a procedure to your application called SecwinRegisterProduct. If you're wanting to use Access Control, then run the template utility CreateAccessControlWindows now as well. NOTE FOR CLARION 9 USERS: At the time of writing this, there is a bug when importing a TXA into clarion 9 which requires you to open each imported procedure that has a prototype. You need to do this now.
  3. On the Frame procedure add the User Screen Security extension template (if you have not already added it)
    In the following template prompts of the Global Extension Template:
    a) Click on the License Check and Restrictions button.
    b) On Levels Tab : Set level to Demo
    c) On Action Tab : Set action to Disable all controls except.
    d) Select controls which you want still to be available if the program has expired. These typically include, ?Exit, ?HelpAbout and ?RegisterProduct (which you'll add just now). Note that you also need to activate the menu name of these items if it exists (e.g. ?FileMenu). If your menu does not exist in the list, then you need to add a Use Variable to that Menu in the Menu Editor (in the Window Formatter)
  4. On the Frame procedure add the User Login Here extension template (if it's not already there.)
    For the Options on the Extension
    a) On the Login Options tab set the Unique Area Name to Main
    b) On the Login Options tab set the Make login optional to end user switch ON (if you are not wanting to use Access Control)
    c) Optionally set the Allow 30 day demo option On or Off...( on is usually recommended).
  5. Go to the Frame procedure and add the Create Secwin Menu. If you are not going to use Access Control in this application, check the Disable Access Control Items checkbox.
  6. Compile and run your application. Depending on your choice in 4c you may or may not see a "Your product has expired" warning straight away. i.e. If you set the Demo mode on then you're likely to get an instant 30 day demo license. If however you left the switch off then you will need to register your program at this point.
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.


JumpStart: Adding Logins and Passwords

This is a quick way to get going implementing the Login and Password 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.

  1. Run the Create AccessControl windows template utility from the Application | Template Utility menu item in the Clarion IDE.
    NOTE: If it's a legacy app, use the CreateAccessControlWindowsLegacy, and if it's an ABC app, use the CreateAccessControlWindowsABC.
    This will add a number of Secwin windows to your application (you'll probably want to do this in your data dll in a Multi-DLL application or in a dll one up from the data dll - we'll call that the security dll). If you are wanting to use the Licencing and Registration part of Secwin, then run the CreateMyRegisterProductWindow template utility now as well.

    If you don't get the windows, then you're using the wrong template utility (i.e. the ABC one for legacy or  visa-versa).

    NOTE FOR CLARION 9 USERS: At the time of writing this, there is a bug when importing a TXA into clarion 9 which requires you to open each imported procedure that has a prototype. You need to do this now.
  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):

    function overrides screenshot

    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:
    • Change Login Item Procedure: SecwinChangeLogin
    • Browse User Groups item: SecwinBrowseUserGroups
    • Set User Access item: SecwinSetAllAccess
  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.


JumpStart: Adding Screen, and Control, Access Control

It's unlikely that you'll limit your access control features to just a login. You'll also want your customers to be able to control who goes where, and does what. this section is designed to follow on from the Adding Logins and Passwords section, so if you haven't done that, then do that now. Which is why this section is also in the QuickStart.

The User Screen Security template allows you to protect any window in your application, and also to protect individual controls on that window. Actually the template also checks the licensing settings for that screen, but those features are discussed in the section called Adding the Licensing and Registration features.

To Add the extension to your application simply go to the procedure you want to protect, Click on Extensions, Insert and select User Screen Security from the list. the procedure has 4 basic options;

a) Screen Name : Leave this blank and the procedure name will be used. If your procedure name is 'LEVEL' then you must name this something here, as LEVEL is a reserved Secwin word.
b) License Check and Restrictions Button : This controls all the license requirements for this window.
c) This procedure doesn't have a window : this is used when you add this extension to a report (usually for Licensing reasons).
d) Disable Screen Security here : Allows you to disable this template without losing all of the options you've set.
e) Control Restrictions Button : This is the place to set the screen security restrictions.

When you press the Control Restrictions Button you'll see a list of protected controls (which is probably blank to begin with). Click on Insert to protect a control. This is possible the most complicated bit, it's where you set which controls you want to protect, and so on.

Unique Bit Position : This is simply a number from 1 to 252. Start from 1 and avoid, if you can, missing any numbers out. It's not too serious if you do. DON'T move items around once you've started shipping your program.

Name : This is a name for the column on the Set Access Screen. Use a simple name, like for the Delete button use Delete, for the Print button use Print and so on. This name is limited to 7 characters long, so use something short.

Use Equate : This is the Equate for the control you want to protect. Select it from the drop-down list.

List box Column : If the control is a list box, then you can protect an individual column in the list box if you like. For example you might just want to suppress the Salaries column. If so, enter the Column Number here.

Action : This determines what should happen when the user does not have access to a field. Button controls are typically disabled (Menu Items MUST be Disabled, not hidden). Entry Fields are often hidden. However the action is up to you.

Attach Other Controls : In some cases you want a group of controls to be set, and unset, together. In this case click on this button and you can add as many controls as you like. Ultimately if the user has access to one of the controls then he'll have access to them all. This appears as a single setting on the user's screen.

Repeat this procedure for all the windows that you want to protect. I know this sounds like a lot of work, and it may be a couple of hours worth the first time you do it, but it's much easier than writing the code, and gives you full control over what's being set.

MULTI-DLL USERS need to check out the

JumpStart: Adding Runtime Access control to a NetTalk Webserver application

This is split into 2 phases (NOTE: READ EACH STEP AND CAREFULLY IMPLEMENT BEFORE YOU DO ANY TESTING):

NOTE: DO NOT USE SECWIN LOGIN IN A MULTI-HOST ENVIRONMENT AT THIS STAGE. Also, all forms and browses that require runtime access control should be in the same app at present.

Phase 1 (gets you going with Access Control in your application)

Note: Requires NetTalk 5.38 or higher, Clarion6 or higher. Recommended: In Memory Driver (from SoftVelocity).

  1. Open your dictionary and import the Secwin Memory tables from the file SecwinNTWStables.txd - or if you don't own the Memory driver, you can import the SecwinNTWStablesTopspeed.txd.

    This file is located in your
    \Clarion6\3rdparty\Libsrc folder or your
    \Clarion8\accessory\libsrc\win folder.

    CapeSoft recommends you use the In-Memory file driver option if you own the In-Memory Database Driver. A stored file will expose your operators to interrogation, so this is not recommended, unless you have complete control over the machine that the NetTalk server resides on. (If you need to know about what these are for, check out: FAQ0.7

  2. Open your NetTalk WebServer application and add the Activate CapeSoft's Secwin global extension to it.

    NOTE: You must set the encryption in the Global Extension on the General tab. This will be primed to a random value for you, however you may want to change it, especially if this application will be sharing the DSSW file with another application.

    Encryption code

    On the 'Files' tab, set the 'Create security files' to 'Allow'. (Note: You will need to set this to 'No' later).



    You must also set the Position of the Data files to where your data store is (for testing, you can set it to the EXE directory, and set this later).

    On the 'Login Options' tab, check the 'If no user exists automatically add' checkbox. (Note: you'll probably want to uncheck this later during the user Self-Insert section).



  3. In the application, go to the WebServer procedure.
    Add the User Login Here extension template to the procedure.



    You don't need to set any options - the default values will be sufficient.
  4. Still in the WebServer procedure:
    Go to the NetTalk or NetSimple Object(x) extension template, on the settings tab, go to the Security sub-tab and UNCHECK the Delete Session on Logout


  5. Clarion 7 or Clarion 8:
    Go to the Application menu, and select the Template Utility option (or just press Ctrl-U).
    Choose the utility called CreateNTWSAccessControlWindowsABC.



    Clarion 6:
    Clarion 6 struggles to import TXA's from a template utility, without dropping some critical information. However you can import the TXA yourself using the File menu, Import Text option. The file you want to import is c:\clarion6\3rdparty\libsrc\SecwinInNTWSABC.txa

    NOTE:
    This will import the procedures you'll need in your webserver application. Two of the procedures that you may already have is the SendEmail and GetSetting procedures. If this is the case, click the 'Rename' button when it appears during import. Both of these procedures are called from the SecwinWebLoginForm.

    NOTE FOR CLARION 9 USERS: At the time of writing this, there is a bug when importing a TXA into clarion 9 which requires you to open each imported procedure that has a prototype. You need to do this now.
  6. Go to the WebServer procedure, NetTalk extension, Settings / General tab.
    Set the Login page option is to 'SecwinWebLoginForm'

    NOTE: If your application requires that people login (i.e. no access to the site unless they're logged in), then you can set the Default Page to the login page as well BUT YOU MUST set your URL On Click of the Login_btn on the SecwinWebLoginForm to the page the user must go to on successful login:



  7. Go to the Procedure that contains the menu. This is usually PageHeaderTag.
    Go to the Web Menu Extension.
    Click on the Add Secwin Menus button. (If this button is disabled, then save and close your application, and re-open and come back here).
    You'll see the 'Security' and 'User' menus appear in the Menus list with the following items on each menu:

    Security:

    User:

    Often times the Index page has it's own access rights apart from the menu, so you need a mechanism to specifically set the menu item's access (Checkout the NTWS FAQ in this doc for details). You do not need this for each screen who's access you need to manage because in browses and forms, you can use the key icon in the tab heading to access the Set Access window.

    NOTE: For you Set Menu Access menu item, you need to set the Item's options as follows:



    The parameters options should read '_Screen_=MyMainMenu'. MyMainMenu is the Secwin Friendly name of the procedure that contains the menu. If it has not been set, then it's the name of the procedure. The Secwin friendly name is located on the procedure's properties on the Security tab:



  8. Secwin allows you to protect access to Browses and Forms. Repeat this step for each browse and form you wish to restrict.

    Go to the Security tab, and check both the User must be logged in and the Runtime Access controlled by Secwin checkboxes.

    This will provide access control for the procedure. The identifier for the procedure defaults to the procedure name, however you can enter a more friendly name if you want.





    NOTE: See Combining procedures' security access settings FAQ for neat ways of setting 2 (or more) procedures' access control settings in one place.

  9. In addition to protecting the whole procedure, you can also protect specific controls in the procedure. This step is optional and can be applied on a procedure-by-procedure basis as needed.

    Aside: Secwin uses the concept of "groups of controls", and allows you to limit access to the "group of controls" on a user by user basis. (Users can also be grouped together if you like, that's not what we're talking about here - this is about control groups on a single procedure.)

    Now, of course, you can have just one control in a group, but it's also possible to put multiple controls together. For example, on a browse you might group the INSERT, CHANGE and DELETE buttons together into one EDIT group. You might then group some sensitive browse columns together into another group.

    Browses:

    On a browse you can assign the individual browse columns into one or more control groups (groups), and you can also assign the "browse buttons" into one or more of these control groups. Each control group has a number (starting with 1, going up to 2, and so on). Each control group must have a unique number, and it must be sequential (i.e. don't miss out numbers)

    Start on the Form Tab. Click on the Secwin Controlled Buttons button. Here you can assign the INSERT, CHANGE, COPY and DELETE buttons into one or more groups. (Just use a number for now, we'll assign a name to the group in a moment.)

     

    NOTE: The controls with controls with '-' in front are not added to a group. The others show the group number in brackets after the control.

    NOTE: It is important that your control group numbers are sequential starting at 1. Secwin will stop at the first number it finds (up to 248) that is not assigned to a control group.

    Next go to the General tab, to the Fields list. For each field that you want to protect (fields can include buttons, text, links, etc.), go to the Security Tab (it's on the top row of tabs, on the far right). Again set this column into a control group. This controls when the column will be displayed.



    If the browse column can be Edited-In-Place then you will see a security tab there where you can determine who has rights to edit the field.



    NOTE: You can set the edit group to the same number as the one used for the edit buttons if you like.

    When all the browse columns and buttons (that you want to protect) are set, then go back to the Security tab for the Browse itself. You should now see a list of groups is the Secwin Access Groups list.



    Going into each group you can change the "name" of the group. This name will appear at runtime, on the Set Access screen, so use a nice human-readable name. For example for the browse update buttons I call the group 'Edit'.

    Forms:

    The same idea applies to forms. First go to the Fields tab, to each field you want to protect, and to the Security tab for that field.



    Once you have done what you need to the fields, go to the overall Security tab, and edit the names of the Security Access Groups, as you did for the Browses.

    Menus

    By now the process should be familiar. For each menu and/or menu item that you want to protect, assign it into a group. Then when you've done that go to the Security tab and set the group names to something friendly.

    At Runtime...

    At runtime, if you are logged in as a Supervisor (and hence have the right to set the access rights for others) a small padlock icon will appear on Browses, Forms and Menus. When you click on this padlock a list of all the Operators will appear, and each column will be labeled according to the name you set. You can then determine who has access rights to which control groups.
Right now, you're good for a trial run, so go ahead, compile the app and run it. You can log in as Demo/Demo (user/password). This is the default user that is (by default) set to be created if no users exists. NOTE: DON'T BE TEMPTED TO ADD USERS AT THIS STAGE!! READ ON FOR MORE INFO.

Phase 2 (Handling user self-insertion and password retrieval):

NOTE: it's a good idea to use the users email address as their login (This is on by default).

You need to decide:
  1. How users will be added to the system. Self-Inserted users allow a user to insert himself to the system. This is common for Forums, and other web communities. In this scenario there is no restriction to a user adding himself.

    Alternatively, there may be an existing list of customers/users/suppliers that can be "activated". In this case, they would enter their email addresses to "create themselves as a user" and this email address is tested for validity against an existing email address in the database. ClarionShop does this for returning customers. The self-inserted user has a basic access, and once he's self-inserted, the supervisor can upgrade his access rights if required. This approach is the default, (one of the menu items added above was a Users browse that supervisors can add to.) See below for more instructions on adding Self-Inserted user functionality.

    The alternative to this approach is where users are added by an existing supervisor. This is more common in applications with private data, for example the supervisor of an accounting system would grant access to new users on a case-by-case basis. This approach is the default, (one of the menu items added above was a Users browse that supervisors can add to.) See below for more instructions on adding Self-Inserted user functionality.

  2. What level of access self-inserted users will be allocated. Typically a self-inserted user is automatically placed in a user group with fairly limited access rights. However they can also be assigned no-rights until a supervisor approves them.

  3. Which method of password retrieval you are going to support.

  4. How the first supervisor gets created
1. For self-user insert:
  1. Test the users against a pre-determined list (like customers or suppliers). NOTE: If this is a public site, you need to be aware that email farmers can use the create users as a method to farm email addresses. The method they'd use is to "enter" random email addresses, and then test the response. If there's an "invalid email address" note, then they keep going until they find an email that produces a different response. See FAQ 0.1 for a complete solution.
  2. Use a captcha to ensure that only humans can enter their data. You'll need Draw for this, and there's a Captcha example that you can use as a spring-board to add a captcha to the SecwinWebLoginForm.
  3. Use a combination of 1 and 2 for maximum security of self-user addition.
2. What level of access self-inserted users will be allocated. (if you're supporting self-user insertion).
  1. Create a Basic Access group, and assign the access for that particular group. Assign each new user to that group. See FAQ0.1 NOTE: If you are using this approach, then you must either programmatically create the user group (as in the NTWS example that ships with NetTalk) or ship a pre-configured dssw5 file that has the basic Access Group pre-added with the necessary access settings for each screen. In the example, the user group has been programmatically added.
  2. Similar to (1), but copy the access. The new users' access become independent of the group (which can be a good or bad thing). see FAQ0.1
  3. The new user gets NoAccess, and must be assigned by the supervisor to a group, or his own access settings. See FAQ0.1
3. Next you need to decide on the method of password retrieval. Option 3.1 is the recommended approach.
  1. On forgot password screen, the user confirms with his email address (or login if it's not the same as the email address). Password is then reset, and a link to force the password change is mailed to the user. A variation is to add a captcha to the Forgot Password screen. Which just protects your system from being hit by a automated system farming for email addresses. You would do this in the SecwinWebLoginForm procedure. In the imported TXA there is a built in email farming protection mechanism.
  2. Preset questions and answers are stored when the user creates himself. These are presented upon a password reset request. Similar to (1) in that a URL is sent to force a password reset. The major problem with this method is that case-sensitive answers are an issue. Also spelling, and change of opinions (for opinion type questions). It seems that this solution type is less popular in automated systems these days.
  3. A variation of (2), where the password is presented on screen (or emailed to the user). This is the least secure, and not recommended.
4. How the first supervisor gets created
  1. By default, the Secwin global template is set to create a supervisor if no users exist. If you like, you can keep going with this approach, just change the default user and password to something unique to your application.



  2. In secwin desktop applications, the first time you run the application you're prompted to create the first user, which is a supervisor. This is an approach you can take with the web server application as well. In this case, on the Secwin global template, uncheck the "If no user exists automatically add" checkbox.
When you first run your application:
  1. From a browser, Login with the default user (if you have setup a default user) - or create your first supervisor and login with that login.
  2. If you have enabled users to self-insert, and you want your users to have a set of basic access settings, then you need to create a Basic User Group for the default access settings for self-inserted users, and set the access settings for that User Group. Once completed, save this dssw5.tps file to your install, as this will become the default dssw5.tps file that you ship with your application.
  3. You need to go to your Secwin Global Extension template, and set 'Create security files' to 'No'.
  4. From there on, you can create users and user groups and assign webpage and control access.

    In your browses and forms, use the key icon in the title bar: to get to the set access window to control the access that each user has to the window and the control groups in that window:



    Use the check boxes to allow a user access or to hide/unhide certain controls. In the above, both user groups have access to the MailboxesBrowseControl procedure, but the Edit and Size Limit Edit control groups are not displayed for users belonging to the Basic User Group.
NOTE: When you add your first user, the system will attempt to email the password reset to the new user. The Email details will not be set at this point, so you'll need to go into the GetSetting procedure and edit it based on where your settings are stored. You'll need an EmailServer, EmailPort, FromAddress, HostAddress. The host address is the base address that the user will click on to get to your website. By default, the GetSetting procedure stores (and retrieves) it's settings from Settings.ini in the application directory. This is not recommended for your application (for a  Windows compliant data location).

Changes you can make in the imported NTWS procedures:

  1. In the SecwinWebLoginForm procedure, you can force a long password, or test for specific character patterns in the verifypasswordconfirmed routine.
Check out the FAQs if you are not getting the results you're wanting.

What to Read Next

You've probably noticed a lot of possibly exciting template switches in your Secwin use so far - if you want to know more about what each switch does then check out the Secwin Template Reference.

If you really want to start exercising some power, then check out the Secwin Technical Reference. This contains descriptions of all the Secwin functions available to you.

Of course if these docs don't explain something clearly enough - or if you need a question answered then don't hesitate to contact  - we're there to answer your questions.
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

User Guide

Access Control

Overview of Access Control Features

Access Control features allow the user to limit access to his application based on who is using the program. This is necessary in many database applications where you wish to expose some of the users to more data than others.

The primary feature for all Access control is Logins and Passwords. This allows the computer to determine who is using the program, and is essential for all the other features to work. For a complete explanation and details on how to implement see the section called Login and Password Access Control.

The next most common features is being able to limit access to screens, and controls, within your application. This is taken care of using the Screen Security template which is discussed in the section called Screen Security Access Control.

The flip side of implementing all this access control, is how the end user goes about managing it. Read about this in the sections called Operator Browse and Form screen, and the Set Access Rights screen.

Ancillary User Functions, like Change Password, Change Login and Lock Screen are also helpful at this point.

User Groups are useful for grouping users together. This can simplify the setting of user's access rights at runtime.

Work Groups are useful for programmatic limiting of users. In other words by using the Workgroup field you can group users together and limit their rights in your own way.

Advanced Programmer Functions describes some of the functions available to the programmer for doing their own advanced functionality.

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.

Login and Password Access Control

The basis of Access Control is the concept of each user having their own Login and Password. In it's most basic form Secwin allows you to protect a program simply by requiring a valid Login and Password before it will run. This is described in the QuickStart section Adding Logins and Passwords. Not surprisingly though even a function as simple as this can have some quite complicated options.

Security will always be a balancing act. The opposite of security is convenience, foolproof security is almost impossibly inconvenient, while simplifying it almost always leads to lower levels of security. With Secwin you can set very tight security, but unless it's absolutely required, your users won't thank you for it. One of your first jobs is to determine how tight the security needs to be, and implement it appropriately.

Most of the options when it comes to the Login screen, apply to the password. these options can all be set on the User Login here template and include things like minimum strength passwords, case sensitivity, and frequent password change enforcement.

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.

You can choose to password protect an entire program with one login and password (by far the most common approach), or divide the program into multiple areas, each area having its own login screen. In the case of multiple logins the same user would use the same user code and password for all the areas. however they may not be granted access to all the areas, and their status from one area to another can change.

Multiple applications using Secwin, and sharing a common dssw5.TPS file, will share a common list of users and passwords. Thus a user has the same login code and password to all the EXEs that he has access to. If he changes his password in one place, then it will change for all his logins.

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.

Advanced : Although it is most common to have the first Login screen appear when the Application starts, it is possible to leave the Frame procedure, and some of the sub-ordinate procedures unprotected, and just require a login when a certain procedure is run, for example a Report, or System Settings procedure. This is done by removing the Login extension from the frame, and adding it to the procedures where you do want the users to Login.

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.

Operator Browse and Form Screens

The Operator Browse and Form screens are used to manage the user list for the program. They're also able to group users together (into User Groups) but that is discussed in a section called User Groups.

The Operator Browse screen should be on your Application's main menu - as described in Step (3) of the QuickStart section called Adding Logins and Passwords.

Any Supervisor can add new Users using these built-in Operator Browse and Form Screens. On the Form are the following fields;

First name & Last name : These apply obviously to the operator.

Login : This is the Login Code the user will use to identify himself to the system. Note that the supervisor cannot set the password for the user. The password will default to be the same as the Login Code, after that only the user can change it. Note: The login cannot be purely numeric. It must contain at least one alpha character (see the ds_GetProperty function reference).

Level : Set the User to be either another Supervisor, and Operator, or a User with No Access to this Area.

Default Access : If the User is an Operator, then you can set their Default Access. this is typically either All Access, or No Access, but it can also be set to the Login code of another Operator. In that case the new operator will assume all the current Screen Security settings of the selected Default Access operator. Note that this will only be for this application name (set in the Secwin Global Extension template) - not across every application that uses that dssw5.tps file. (See Definitions for more details)

User Group : If the User is an Operator, then he can belong to any number of pre-defined User Groups. For complete information on what User Groups are, read the section in this guide entitled User Groups.

Workgroup : You can assign a Workgroup number to the user. For more information on Work Groups, see the section in this guide entitled Work Groups.

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.

Screen Security Access Control

The Screen Security Access Control is handled by a template called User Screen Security. This is added to each procedure where you want it. See the QuickStart section called Adding Screen, and Control, Access Control.

Wherever this extension is added, the end user will be able to set his own security using the Set Access Rights screen.

Set Access Rights Screen

While the Operator Browse screen lets you set access rights to the whole program, The Set Access screen allows the end user to limit access to specific controls, and windows within the application.

The main goal here is simplicity. The idea is that your customer must be able to work this screen, regardless of their computer skills, and you must be able to teach it to them in a quick and simple way. To this end we have avoided the use of complicated windows which allow you to set multiple settings at the same time.

The screens, and controls, that support this feature are set by the programmer at compile time, but the actual access rights are set by the end-user when he runs the program. As the programmer you can find out how to activate the security by reading the section called Screen Security Access Control. In this section we'll concentrate on how the end-user uses that security.

In order to set security rights the end-user must be logged in as a supervisor.

By going to any window with the User Screen Security extension, and pressing Ctrl-F8, they will get the Set Access window. This window will have a list of the Operators on one side (Users with No Access, and Supervisors are not listed). User Groups will also be listed, and users already assigned to groups are not listed.

The list takes the form of a spreadsheet, with the names on the left, and the access rights on the right. By simply double-clicking on the displayed rights, access can be changed from Yes to No. Closing the screen is done by clicking on the Close button.

So if the user wishes to stop users Deleting his Customers, then simply by going to the Customer Browse, and pressing Ctrl-F8, he can limit the access to the Delete button.

Note: You can make use of the Secwin Global SetAccess window as well, which makes setting access points much easier than using the SetAccess screen.

Note: You must add the check.ico and uncheck.ico to your multiproject resources if you are building a multiproj application.

Ancillary User Functions

These functions are designed to be added to your program as features for your end-user to use. The first one Change Password is likely a necessity, while the other 2 Change Login, and Lock Screen are optional.

Change Password : This allows your end user to change his password. He will need to enter both the old password and the new password. On your login extension template you are able to set minimum password requirements (Force Password Change - Force Long Password). You can also make your own Change Password screen, see the section entitled Making Your Own Secwin Windows. To use the built-in Secwin Change Password window see the Change Password Code template.

See FAQ3.4 for details on how to retrieve lost passwords.

Change Login : This function allows the users to change from one user to another without exiting the program. You can make your own Change Login screen, see the Making your Own Secwin Windows section for details. To change the Login using the build-in Secwin Change Login screen see the Change Login Code template.

Lock Screen: This blanks out the screen so that others can't see it. Only necessary in specific situations. Note that this does not protect the whole machine, only the running application. The user is required to re-enter their password before continuing. To call the Lock Screen function use the Lock Screen Code template.

User Groups

If you have a large number of users then it may not be convenient to set the access rights for all the users individually. In this case you can create groups of users, cunningly called User Groups.

To create a User Group use the Operator Browse screen, and User Group Details button.

To put users into groups use the Operator's Form. A List of User Groups is provided that the user may be allocated to. In Secwin 4 the User may be allocated to multiple UserGroups. Note that this list box will only be available if the User is set to be an Operator.

Setting the rights for a Group is exactly the same as setting for an individual. Simply use the Set Access screen while the program is running.

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:

When a user is assigned to a user group he loses his individual access rights and only takes on those of the user group. If he joins multiple user group, then his access is an "or" function of the user group's rights. For example: one user group is denied access to a particular screen and another is allowed access, and the user belongs to both user group, he will be allowed access.

Work Groups

Work Groups are different to User Groups, they require more effort from the programmer (you need to handcode where access is limited to a workgroup, or where a user is limited by belonging to a workgroup) - and can be confusing to the end user. The difference between User Groups and Work Groups is that user groups' access are runtime assignable - whereas workgroups' access is programmed into your application. A user is assigned to a workgroup at runtime (hence the confusion on the supervisor's part of where the access points are), even though the access points are set at compile time.

They are essentially a number (a long) which you can store with each user.

This number can be used to limit browse records which are available, or it may be used to perform some specific access control feature of your own.

The Work Group number, for each user, is set on the normal Operator Form. Each operator can only belong to one workgroup.

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.

Bypassing Access Control

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 dssw5.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 dssw5.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 dssw5.tps file, you need to make sure that dssw5.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).

Multi-DLL Applications

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.

Licensing and Registration

Overview of Licensing Features

The basic goal of the licensing features is allow you to sell your program in different flavors, and yet have a single set of install files. In other words by making use of an Activation Code, you can limit, or extend, your program based on the amount that the client pays. You can use all the licensing features, or more likely, you'll just make use of a few of them. In this User Guide each feature will be discussed in more detail, so take a moment to read though them and decide which ones you want to use. These features include;

Product Branding through the use of the user's company name, and a serial number. this means you advertise on your screens, and on your reports, the name of the licensed user. This makes it difficult for illegal user to distribute reports etc. For more information read Branding on Reports, and Branding using Logo Screens.

Levels allow you to enable a piece of your program, then a bit more, then a bit more, and so on. Each Level is a superset of the previous levels - in other words each level includes all of the previous level's features. By default these levels are named (in order) Demo, Lite, Standard, Professional and Enterprise, however you can name them anything you like. See Using Levels for more details on this feature.

Automatic Demo Licenses allow you to distribute demo versions of your program that run only for 30 days. Please note that this feature is very 'strong', so testing is difficult. Read Automatic Demo Licenses for more information.

Optional Modules allow you to activate up to 30 separate, unrelated, modules, in addition to your main program. For example in accounting applications you often purchase a combination of modules - General Ledger, Debtors Ledger and so on. See Using Optional Modules for details on this feature.

Concurrent Network Copies allows you to limit the number of simultaneous, concurrent, users on a network. The user can load your program on any number of computers, but only a limited number of users will be able to access the data at any one time. See Using Network Copies.

Users currently logged in. This feature is something of a bonus that you get when you implement licensing in your program. Because of the concurrent network copies feature, Secwin is able to track who is currently logged into your program. This can be very useful for network updates, as you can ask users to quit the system while you upgrade the program. See Using Network Copies.

Expiry Dates allows you to control when the program will cease working. This can be used for distributing 30 day demo versions of your software, or for licensing your software for limited periods of time (for example yearly license renewals.) See Using Expiry Dates for the specifics.

Counters are somewhat less common. Essentially they allow you to sell your program based on the number of times it will be run, or the number of reports that will be printed, or something like that. Alternatively you might use it just to store an extra number which you want to use somewhere in your program. See Using Counters.

All of the features are activated and de-activated through an Activation Code. This code is generated by you, using either the Register example application or using an online activation code generator (like Secwin Online Server).

If the user doesn't have sufficient access then the License will fail. The exact action taken when this happens is determined by you - see the section called When the License Fails.

Some Activation Code secrets

Activation codes contain the date on which they were generated, and you can specify the life length of the activation code. By limiting the period that the activation code is valid, you can limit activation codes being passed around and used by many users over an extended period of time. Don't get confused between this date and the Licence Expiry date though, these are 2 completely separate features.

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.

Branding

Branding on Reports

An effective, and non-intrusive (to the registered user), form of copy protection is Product Branding. One technique you use for Product Branding is to put the name of the Company that registered the software on the reports.

Unfortunately given the large number of report templates available, and the fact that most reports are heavily customized, if not hand-written, it's not possible to write an Extension Template that will work in all situations. There is however a simple Code template, called Code : Call CurrentLicense, which will do most of the work for you. You can find details about the template here.

Branding using Logo Screens

One of the ways of Branding your product is to put the Licensed name of the user on the screen as a background to your Frame.

As you may know, it's not possible to put any controls in the 'Window' part of a Frame procedure. The best you can do is apply a bitmap graphic as the wallpaper to the window. As we want the background to be dynamic (to include the licensed user's name) a bitmap wallpaper isn't going to be good enough.

Secwin overcomes this limitation by allowing you to create a separate window procedure, put whatever you like in the window, and make this window the 'background' to the window part of the frame.

You use the normal Clarion Window template to create the window. You can put pretty much anything you like on the window - I often use the product name, and maybe a product logo here. Of course the most important thing to put here is the name of the current License holder. Note this is not the name of the user (although you could put that here as well if you like), but rather the name of the Company which has licensed the program.

There is one requirement for the window -it must have the MDI attribute turned on. If you don't do this, instead of the window being at the back, behind all your browses and forms, it will float to the front.

Some other suggestions which make the window work well are;

  1. Set the position to 'center'.
  2. Turn the Clarion feature to 'Save and Restore the Window position' off.
  3. Remove the Caption, and the System Menu attribute.
  4. Set the 'border' of the Window to 'None'.

The second requirement is to add the Secwin Extension template, called Extension : Make Logo Screen, to the window. This adds the code necessary to make it a background window. You can read more about the template, how to add it, and the options it has, here.

The last step is to add code to your program that Starts the Logo screen. Of course there is a Secwin template to do this as well, it's called the Extension : Run Logo Screen template, and you can read more about it here. This template is added to the Frame procedure itself.

See the Examples section for an example of this.

Hardware Copy Protection

In some cases you may want to 'lock' a particular activation code against the actual machine. There are a number of different hardware IDs that you might like to use - all of which have their weaknesses. You can use the ds_GetDriveSerialNumber to return the serial number of the hard disk (although some manufacturers are not particular astute at generating unique serial numbers). Alternatively you could obtain the MACAddress of the PC - although this could change as additional MACAddresses are added (in the form of extra network cards or virtual networks like Hamachi or Sonicwall). Although this number can be changed by the end user, given the correct tools, it is a reasonably effective way of ensuring that the data is not moved from one machine to another.

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.

To implement a test based on this check, add the following code anywhere in your program, After the user has logged in;

if ds_CurrentSerialNumber() <> ds_GetDriveSerialNumber()
  ! oh dear - pirate code goes here....
end


Typically you would also display this number on your about screen. That way, when issuing the code, you know what to set the Serial Number to. In other words the user needs to report to you his serial number (he shouldn't know it's the same as his hard disk) so you can generate a code which matches that number.

When issuing the activation code (if you're not using Secwin Online Server) - you will need to add this hardware ID to one of the additional strings in the licence information:

Hardware Protection Licence Issue screenshot

In your SecwinRegisterProduct window, enter the following code in the Drop event for the XML drop region:

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


Using Levels

It's common these days to find different Levels available for the same program. For example a program with Lite in the name normally means there's a (more expensive) version, with more features, available. Another common feature is to distribute a free demo version which is limited either by time, or by feature set. ( The time option is discussed in the section entitled Using Expiry Dates).

Secwin supports up to 5 levels of the same program, although obviously you may not have need for all 5. The levels are named (by default) Demo, Lite, Standard, Professional and Enterprise. (You're free to rename the levels to anything you like). The idea is that each level is a superset of the previous one, with more features added. In other words the Lite level includes all the Demo features, and the Standard level includes the Demo, and Lite features and so on.

Using the User Screen Security Template you can set any of your procedures so that they require a specific level before they'll operate. For example you might set a procedure to require Level Lite - in which case it won't work in Demo mode. Or another procedure might require Level Professional, in which case it won't work in Demo, Lite or Standard Levels.

If you have a procedure where you want to use a Level restriction, then add the Screen Security extension to the procedure, click on the License Check and Restrictions button, and select the Level you require on the Levels tab.

Automatic Temporary Licenses

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.

Automatic Temporary Licence Setting screenshot

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 (dssw5.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.

Using Optional Modules

Optional Modules are a lot like Levels, but while Levels work by each level including the previous level, Optional Modules work as completely separate units. The most common example of this approach is the Accounting Suite, where you can purchase any combination of General Ledger, Debtors Leger, Creditors Ledger, Payroll, Stock Control and so on.

When you issue an activation code, you can enable, or disable, up to 30 optional modules. Within your program you can use the User Screen Security extension to set any of your procedures to require one, or more, optional modules. You set the Modules require by going to the License Check and restrictions bottom, to the Modules tab.

Using Network Copies

One of the settings you can set when setting an Activation Code is the number of concurrent copies of your program that can be running at any one time.

The idea is that, in a network situation, it's a good idea to activate the program on as many machines as possible. By exposing more of the users to your program, ultimately means more money for you. So you load your program onto any number of workstations, but use Secwin to limit the number of concurrent connections that can be made to the data.

Using Network copies is very easy. Go to the User Login Here Extension, to the Licensing tab. Set the Licensing to be active, and set the Unique 4 Character License code. If you wish to turn off this feature then check the Disable Network Licensing switch. The number of copies that a user can have at one time is set as part of the Activation Code.

Secwin will use these 4 characters, plus a 4 digit number, to create a number of LIC files in your data directory. Each user as he logs in, will open one of these files using a Read/Write Deny Write file setting. For the duration, while he is logged in, this file will be locked. If your program GPFs, or the workstation is rebooted then the server will automatically unlock the file.

You can see a list of who's logged in by making a call to the ds_CurrentlyLoggedInEx function.

Note: This feature is only available currently for ISAM file users (using TPS, BTrieve, Clarion, etc file systems). SQL users will need to build in a TCP/IP client/server system to verify with other applications whether the number of current instances exceeds the permitted Network Copies. This is outside the scope of Secwin and requires a template such as NetTalk to implement this functionality.

Using Expiry Dates

This is the only option which is not actually set by the user on the Product Registration screen. This is because you may not actually want your end user to know there is an expiry date. The date itself is set when you generate the Activation Code. When the user's PC goes past this date, then the license will fail.

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.

Using Counters

Counters are probably the most unusual of the Secwin features. Typically they allow you to restrict the number of entries into a table, or to restrict your program based on the number of times a procedure has run (reports, or a procedure).

The counters for your client, are set when you issue the activation code. You can use as many counters as you would like, each counter is identified by a label. The means that the label of the counter in your Register app (i.e. the program that issues activation codes) must match the label used in the RegisterProduct window, which must match the label as it is used in your application. This is simple for Table restrictions, but if you're using it other than for table restrictions, you need to be careful of this 3 way name match that is necessary.

Table Restrictions:

For table restrictions, you need to:

  1. Add the table to be restricted in your Secwin Global Extension templates (on the Licensing tab).

    Table Limit Restrictions screenshot

    You can specify the table, the licence level range that the limit applies to. Levels below the limit will not allow any records, and licenses above the MaxLevel limit will not apply any limits to the table. The Default limit is the limit that is applied for a Default temporary initial activation licence - as well as what is initially set in the manual registration screen (if you are not using Secwin Online Server to automatically issue activation codes). The Counter Label allows you to associate a user-friendly name with your counter instead of the table name (leave blank to use the table name). Use this name in your Licence code generation program (like SecwinOnlineServer).

    What this will do is add a callback when an insert to the table is attempted and check the licensed limit for that table to verify that table limit has not yet been achieved. If so, then the insert will fail.
  2. In order to avoid the user from entering all the details on a form, and the insert only failing when the hit the OK button at the end of the form, you can add the User Screen Security template to your forms (for that table) - and check the Warn before insert if records are on the limit checkbox and specify the table to check in the drop down below that.

    Warn On Insert Limit screenshot
  3. In your register app, the counter used will be the name of the table (in this case 'Wages'). This is crucial to get the counter to match correctly.
Procedural Restrictions:

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. Your 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:

  1. 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.
For Hand-coding:

To check a counter or decrement a counter manually, use the ds_CheckCounter function to do this. The Counter label that you are checking/decrementing must match the counter in the RegisterProduct window (as well as the registration application that issues the licence).

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.

Using Serial Numbers

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.

When the License Fails

Whenever the user accesses a procedure, and the users' current license doesn't meet the requirements for that procedure, then the license fails. You can decide on the action which must be taken at this point. The action is set on the User Screen Security template. Go to the License Check and Restrictions button, and go to the Actions tab.

The first option, and the most common action, is to display a warning message, and to close the procedure. Typically the procedure will close without any screen being opened, so the user will just see a warning message.

Alternatively you can set it to close immediately without the warning message.

You can also select for the procedure to carry on as normal, but for all the controls on the window to be disabled. Actually you can also override the disabling and allow some of the controls to be enables. This option is most often used on the Frame procedure. If the program starts, and the license fails (maybe it has expired) then you still want the user to access menu items like, Help About, Register Product, and File Exit. By using this option, and specifying these controls, the user will be able to get your information (from the About screen) and use the Register Product screen to enter a new Activation Code.

The final option is for it to call a procedure. This would most often be used when you have created your own product registration screen, and if the license on the FRAME procedure fails, you want it to automatically go to your procedure.

Including additional fields in the Licence

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.

Using an XML file to transfer the licence details

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:
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:

Registe rProduct Window xml File Support screenshot

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.

Using Different Licence Types

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).

The mechanics of Licensing

  1. Your program creates a .Lic file in a common directory (normally the data directory) which it locks while it is open.
  2. The next instance of your application that runs, will find the existing .lic file in the data directory and will attempt to open it. If the first instance is still running (and will still have the file locked) then this new instance of the application will fail to open the .Lic file. It will then check how many licences are available for use and create another .lic file (if the number of licences has not yet been exceeded).
  3. Each instance of you application will continue with step 2 above until the number of licences has been reached, at which point the next instance of the application that is run, will fail.
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).

The Security File

Creating the Security File

Secwin makes use of a data file to store user names and access rights etc. This file is called dssw5.TPS and is stored (by default) in the Windows directory. (You can override the location - see Locating the Security File.) Also, by default, your program won't create the security files. If it did then users could bypass the security by deleting dssw5. (You can also make your program create the files by using the ds_CreSec function.)

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.

You have 4 options for creating the security file.

Locating the Security File

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.

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.

Security-File Driver

Secwin supports storing the security file using a variety of different drivers. These include support for Oracle (via ODBC), Microsoft SQL, PervasiveSQL, IPDriver and ODBC drivers, which means you can use a variety of different databases such as Interbase or MySql. These Security-file drivers are included in the Secwin install.

To use one of these drivers:

Microsoft SQL

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.

PervasiveSQL

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.

ODBC

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.

IPDriver

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.

Creating a Callback Function

In your data-dll (or exe app for single-exe applications), run the "Import a sample SecwinCallback procedure" template utility. This will create a source procedure that you can use to redirect Secwin based on other factors (that you choose). So typically if you wanted to import Secwin tables when upgrading from TPS to SQL, you would code in something like the following:

case pFunction
of ds_ErrorNoSecurityFiles
  case message(pFunction & ' ' & clip(pMessage) & '|Would you like to import the tables from another application?','Note' ,icon:question, button:yes+button:no, button:yes)
  of button:yes
    ds_Cresec()
    ds_ImportTables(1)
    message('Please restart the application')
  end
end
return 1


Now in your Secwin global Extension template, on the Options tab, set the Secwin Callback Procedure as follows:




Customizing the Look and Feel of Secwin Windows

Changing the Logo on the Secwin Windows

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.

Making your own Secwin Windows

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.

Creating the Product Registration window

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):

  1. Select the Template Utility item from the Application menu.
  2. In the Select Utility list, scroll down to the Class Secwin and find the CreateMyRegisterProductWindowABC/Legacy and select it. You will see a SecwinRegisterProduct procedure is now added to your application.
  3. You need to call the SecwinRegisterProduct window from the control that you previously added the Call RegisterProduct code template - or where from where you called your MyRegisterProduct window.
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:

Register Product Window TPL General screenshot On the Messages tab you will be able to set the text of Registration success and failure:

 Register Product Messages Tab screenshot

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

Secwin Counters Tab screenshot

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.

Creating the Global SetAccess window

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:

  1. In the Secwin Global Extension template, on the Options tab you will find a set of prompts to generate an include file (the default extension is .SAC) for all the security points in the application. This file is only used at compile time and does not need to be deployed with your application. Check the Generate inc file with Access points everytime checkbox, and enter a unique include filename that will contain the additions to the Access Points Queue (more about this queue later). For Multi-DLL apps: You will need to come back here and add the name of each SAC file generated by the other DLLs to this list AFTER you have added AccessControl to those applications (and generated the entire project). NOTE that each of your dll applications must have their own unique name for their sac file, as these files are re-generated at compile time.
  2. Run the Create AccessControl windows template utility
  3. In the extension templates of the SecwinSetAllAccess procedure, you will find a Secwin's set access globally control template. In there is a list of the include files that need to be used to create the AccessPoints Queue which is used in the procedure to display all the access points of the application(s). The one that is in the SecwinGlobalExtension template should be automatically added.

    Note for Multi-DLL users: You'll need to add any other SAC files (to this list) that are created by other applications related to this one. You'll probably want to delete the root dll's sac file from the list, as it is normally superfluous (i.e. it probably doesn't contain any access points).
  4. If you have not already added the Create Secwin Menu extension template, then do that now.
The SetAccess window that is added to your application has two list boxes: one for users and one for the AccessPoints.

Global Set Access Window screenshot

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:

Global Set Access Window AP screenshot

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.

Creating the User Browse & Form windows

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).

Creating 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 Login Window)

Creating the Change Password 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)

Creating the Change Login 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)

Creating the SetAccess 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.

Using SecWin in a NetTalk WebServer

Miscellaneous

Using Secwin in MultiDLL applications

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. Clickon This is part of a Multi-DLL Application.
  3. Clickoff Export Secwin data.
In the global extension on each application:
  1. You need to set the "Unique application name" (in the Secwin global extension template) the same in all the applications.
  2. The "Licencing" tab should be setup the same in the all your app files (i.e. the data dll, the main exe and any additional dlls that you want to add Secwin to).

For each application that is using Access Control, you will need to record the name of the generated .SAC file and enter that into the list of the "Files Containing Access Points" in the Secwin's set access globally control template on the SecwinSetAllAccess window (Creating the Global SetAccess window) to get all the access points into that window:

For some assistance with additional settings, check out the Global Extension template

Converting from Secwin 2.x to Secwin 3.x

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.

Distribution

The Secwin DLL names HAVE CHANGED! See the Distribution section, in the Other Information section for specifics.

Multi-DLL Applications

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

Btrieve Users

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 Examples

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.
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:
  • Compile the IP_abc.app and copy the compiled DLL (IP_abc.DLL) to the C:\ClarionDataServer directory (or whatever directory you installed the IP server into).
  • Copy the data in the example's Server sub-directory to the IPServer's route directory.
  • Copy the IP Server driver DLL from your \clarion\3rdparty\bin directory to your \ClarionDataServer directory. If you haven't already done so also copy the Clarion Runtime DLL's to the \ClarionDataServer directory - including C60RunX.DLL, C60DosX.DLL and C60TpsX.DLL.
  • Run the RmAdmin program, and register the IP Server driver DLL and IP_abc.DLL. (This is as you would do for your application's IP driver DLL - which is laid out in the documentation provided by SoftVelocity that comes with the IPDriver install)
  • Compile and run the abc.app.
  • 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.
  • Compile and run the DataDLL.app, the ProcsDLL.app, and the Country.app (in that order).
  • 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.
    NOTE: For a Secwin integrated webserver example application, check out the NetTalk examples.

    Super Users

    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.

    Translating Secwin Windows

    In Secwin 4 and up, you'll hardly have any translating requirements within the actual Secwin DLL - as the windows have all been transferred into your application. This means that you can handle the translating of messages and screen prompts from within your application.

    For the odd internal DLL message you can still use the following to translate the relevant messages (see the Secwin\Demo_Licence for an example of using this functionality):

    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.

    Choosing a language

    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.

    Example

    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.

    Format of a Secwin language file

    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


    PIN numbers

    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 dssw5 security file by an empty dssw5 file. PIN numbers prevent this from being effective by requiring that a dssw5 file be "stamped" with a PIN number before the Application will accept the dssw5 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 dssw5 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-authorized 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 dssw5 file.

    Using an encryption key

    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.

    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).

    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.

    Utilities Shipped With Secwin

    The FileFixer Utility

    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:

    Security Table Corruption Repairer Message screenshot

    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:

    1. Enter your product (in the Browse Products procedure) - include a description (in the Product Name field) - and the application name (this is the Secwin Application name entered in the Secwin global extension template).
    2. Enter the Customer details (in the Browse Customer procedure) - include the customer name, Email address (this will be the from email address of the Request Email) - and the UniqueIdentifier included in the email.
    3. Next is to create a Request in the Browse Requests procedure (this is an incident file). Here you can stipulate how long the Security code issued is valid for, and how many times the Security Files can be repaired during the course of the Security file's validity. Once you've entered all the details, click the send email button - and use your email client to send the email to the client.

    ClarioNet / WebBuilder compatability

    Secwin now supports full compatibility 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 compatibility. 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.

    Using Secwin in a Multi-Proj application

    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:

    1. In your Secwin Global Extension template, find the Files tab and check the Manually include the correct Secwin driver checkbox located in the Multi-Proj support prompts groups.
    2. In your Multi-Proj template, on the Versions tab, locate the project for the IPDriver substitution, and double-click it.

      Multi-Proj Version tab

      On the Resources tab for this Multi-Project version, enter the Secwin IPDriver lib - s6ipdx.lib (if it's a stand-alone project, and not a localmode project)

      Insert Secwin IPDriver DLL into the MultiProj resources
    3. In your application, you'll need to override the driver owner setting generated by the Secwin template in your default module (your main exe):

      ds_InitFileCallback()
      ds_SetAppName('SecwinDemo')

      COMPILE('****',TOPSPEEDDRIVER)
      ds_SetPath('HERE',,)  ! secwin
      ****
      COMPILE('****',IPDRIVER)
        SWDRV::OWNER = 'IP_S6TPS6' & sub(IPDRV::OWNER,instring('.',IPDRV::OWNER,1,1),255)    !This is for Clarion 6
        SWDRV::OWNER = 'S70IPD6S' & sub(IPDRV::OWNER,instring('.',IPDRV::OWNER,1,1),255)    !This is for Clarion 7
        SWDRV::OWNER = 'SLAIPD6S' & sub(IPDRV::OWNER,instring('.',IPDRV::OWNER,1,1),255)    !This is for Clarion 8
        ds_SetOwner(SWDRV::OWNER,SWDRV::OWNER)
      ****
    For a list of the matching drivers to their Secwin projects, see the Distribution section of this document.

    IP Driver Compatibility

    Installing

    In Clarion 6, the IP Server driver DLL is called IP_S6TPS6.dll. In Clarion7.1 and 7.2, the IP Server DLL is called S70IPD6S.DLL. In Clarion 8, it is called SLAIPD6S.DLL
    1. Copy the IP Server driver DLL from your \clarion\3rdparty\bin directory to your \ClarionDataServer directory. If you haven't already done so also copy the Clarion Runtime DLL's to the \ClarionDataServer directory - including C60RunX.DLL, C60DosX.DLL and C60TpsX.DLL.
    2. Run the RmAdmin program, and register the IP Server driver DLL. (This is as you would do for your application's IP driver DLL - which is laid out in the documentation provided by SoftVelocity that comes with the IPDriver install)

    [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).

    1. Check that the the File driver (set in the Activate CapeSoft's SecWin template) - Files tab, is set to Topspeed.
    2. 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 'HERE' (including the quotes).
    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 Server driver 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 dssw5.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 Server driver 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 Server driver DLL resides.

    ds_SetPath(GLO:IPServerSubSir)           !GLO:IPServerSubSir must contain the sub dir containing the dssw5 file.

    Some other Caveats:
    1. If you are using a global variable defined in your dictionary (i.e located on the IPServer) - then you need to open a table before Secwin initializes.
    Limitations
    1. Only support for the TPS driver (i.e. dssw5.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.

    Advanced Programmer Functions

    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 (dssw5) 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

    Global Extension : Activate Secwin features

    Purpose

    This is a Global Extension template which needs to be added to the Global area in order for the Secwin features to work.

    To Include in your App
    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 onInsert
    5. Choose Activate Secwin Features
    Options

    Template Global General Tab screenshot
    Template Global General Tab screenshot

    Template Global Licencing Tab screenshot
    Template Global DLL Tab screenshot

    Template Global Files Tab screenshot

    Template Global Options Tab screenshot

    Extension : MakeLogoScreen

    Visible Effect to your App

    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

    Purpose

    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.

    To Include in your App
    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
    Options
    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.

    Extension : RunLogoScreen

    Visible Effect to your App

    This template calls your logo window, which makes the logo window visible.

    Purpose

    This template starts a thread with your MDI logo window.

    To Include in your App
    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
    Options
    Logo Procedure This is the name of the Logo Procedure to use. The Logo procedure should use the MakeLogo Extension.

    Extension : User Login Here

    Visible Effect to your App

    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...

    Purpose

    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.

    To Include in your App
    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
    Options

    Login Options Tab Override Global Options By default, these options are set in the global template (Global Login Options tab). You can override this here for this instance of the login.

    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.

    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.

    Use User Account Authentication Use Windows authentication to log a user in. The user must still be added as a Secwin user, but the login screen is not presented to the user. For more details, check out: FAQ3.21

    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.

    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 dssw5 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.

    Super User doesn't use a licence If you're using the number of copies licenced feature in secwin, then you can check this so that the superuser does not use a copy when accessing the application.

    Extension : User Screen Security

    Visible Effect to your App

    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.

    Purpose

    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.

    To Include in your App
    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.

    Options
    General Tab 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.

    Screen Name Enter a user friendly screen name for the SetAccess window (at runtime). You can also use this to make 2 procedures use the same access points.

    Disable Access Control here Disables access control in this procedure (if you only want licence checking done in this procedure).

    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.

    Always allow window access This will only affect users that are operators, with default access of No_Access. It's useful if you want to add security to a procedure to protect controls, while not restricting procedure access.

    Don't check access in list box filters  

    This is a CPCS report Check this if this is a CPCS report procedure

    Don't refresh access settings on GainFocus By default, Secwin will refresh the access control on Gain Focus. This is in case another record got added to the table, or changed, that will affect what controls and/or records the user can view/use.

    Don't add this screen to the SetAllAccessList By default, all Secwin screens will be added to the SetAllAccess window. You can check this if you don't want this procedure to be added to the list.

    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.
    Control Restrictions Button Setable You can select whether to control access to this control group at runtime, or to User type.

    Unique Bit Position You are allowed up to 250 groups of controls per window. Each group (a group may be just 1 control) needs a unique, unchanging number, from 1 to 250 . Enter that number here.

    Restriction Name Enter the name of the group here. This name will be used on the Set Access window.

    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.

    Use Equate (Controls to Protect) 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 (Controls to Protect) 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 (Controls to Protect) You can use this list to override the Secwin restriction action for a particular control in the group (see Action above for details). By default, this is set to Default, i.e. the action of 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 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 must 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.

    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, and for which licence level is required for that control to be active.
    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.

    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. Set the column of a list box if you need to hide a column (instead of the whole list box).
    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. You can specify which counter you want to decrement (if you are using multiple counters).

    Extension: AutoPopulateUserScreenSecurity

    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.

    Extension: CreateSecwinMenu

    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.

    Create Secwin Menu Tpl screenshot

    Extension : User Workgroup Filtering

    Visible Effect to your App

    Allows you to use the CWG variable in your browse filtering.

    Purpose

    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.

    To Include in your App
    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.

    Control : Register Product Controls

    Purpose

    This allows you to create a Register product window inside your application (as apposed to using the deprecated RegisterProduct window inside the Secwin DLL).

    To Include in your App

    Use the Template Utility provided to create a SecwinRegisterProduct window in your application.

    Options in the template

    See the Creating your own Product Registration window section for more details.

    Code : Call Current

    Visible Effect to your App

    Allows the user to call the ds_CurrentName, ds_CurrentLogin or ds_CurrentLevel function and place the result on the status bar.

    Purpose

    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.

    To Include in your App
    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
    Options
    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

    Code : Calling Current Counter

    Visible Effect to your App

    Allows the developer to display the current value left in the counter.

    Purpose

    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.

    To Include in your App
    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.
    Options
    Put the result in Enter a field which will contain the result. The field should be a Long.

    Code : Calling Current Expiry Date

    Visible Effect to your App

    Allows the developer to display the current value currently in the Expiry Date in the License

    Purpose

    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.

    To Include in your App
    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.

    Options
    Put the result in Enter a Long field to contain the date.

    Code : Calling CurrentLicense

    Visible Effect to your App

    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.

    Purpose

    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.

    To Include in your App
    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

    Code : Calling CurrentlyLoggedIn

    Visible Effect to your App

    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.

    Purpose

    This code template is designed to be attached to a menu item or button. It calls the ds_CurrentlyLoggedInEx function.

    To Include in your App
    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_CurrentlyLoggedIn code template.
    6. Close the windows in the normal fashion.

    Code : Calling Change Login

    Visible Effect to your App

    Allows the user to call the Change Login Screen.

    Purpose

    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.

    To Include in your App
    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.
    Options
    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.

    Code : Calling Change Password

    Visible Effect to your App

    Allows the user to call the Change Password Screen.

    Purpose

    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.

    To Include in your App
    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.
    Options
    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.

    Code : Calling Get License Details

    Visible Effect to your App

    Allows you to load all the current existing license details.

    Purpose

    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

    To Include in your App
    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.
    Options
    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.

    Code : Calling Lock Screen

    Visible Effect to your App

    Allows the user to call the Lock Screen Screen.

    Purpose

    This code template is designed to be attached to a menu item or button. It calls the ds_LockScreen function

    To Include in your App
    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.

    Code : Calling Operator Browse

    Visible Effect to your App

    Allows the user to call the Operator Browse Screen.

    Purpose

    This code template is designed to be attached to a menu item or button. It calls the ds_OperatorBrowse function with the appropriate parameters.

    To Include in your App
    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.

    Code : Calling Register Product

    Visible Effect to your App

    Allows the user to call the Register Product Screen.

    Purpose

    This code template is designed to be attached to a menu item or button. It calls the ds_RegisterProductEx function with the appropriate parameters.

    To Include in your App

    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.
    Options
    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.

    Code : Calling RunAnotherExe

    Visible Effect to your App

    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.

    Purpose

    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.

    To Include in your App
    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.
    6. Set the name of the program to run as well as any other parameters that the program may need.
    Options
    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.

    Code : Calling Set Language

    Visible Effect to your App

    International language support.

    Purpose

    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.

    To Include in your App
    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.
    Options
    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.

    Code : Calling SetPin

    Visible Effect to your App

    None

    Purpose

    This function is not designed to be added to your main application - rather it is used on the developer machine to stamp dssw5 files with PIN numbers.

    This code template stamps the dssw5 file with an Application PIN number. Pin numbers enhance application security be ensuring that only correctly "stamped" dssw5 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.

    To Include in your App
    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.
    Options
    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.

    Code : Get Activation Code

    Visible Effect to your App

    None

    Purpose

    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

    To Include in your App
    1. Add the code template to a button.

    Secwin Technical Reference

    See Secwin Data Types for the Secwin Specific data types required by some of these functions.

    Please note: These function docs are as yet incomplete - where detail does not exist, please contact CapeSoft Support.

    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_CurrentLicenceDetailsEx 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_SetProperty

    ds_UserInUserGroup

    ds_AddUserToUserGroup

    ds_RemoveUserFromUserGroup

    ds_UserAllowed

    ds_UserAllowed (long app,string calledby,long override,long pUser,<string pUserSite>)

    Description

    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'.

    Parameter
    Parameter 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).
    Returns

    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

    See Also

    ds_LoginUser, ds_ModifyAccessEx

    Example
    Example
    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

    ds_BuildKeys

    ds_BuildKeys ( [Locale] )

    Description

    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.

    Parameters
    Parameter Type Description
    Locale String Optional. A string suitable for passing to the Clarion LOCALE statement.
    Returns

    Nothing

    Example
    Example
    NewLogin String(12)
    NewPassword String(12)
      Code
      ds_BuildKeys ()
      ds_BuildKeys ('My.Env')

    ds_Allowed

    ds_Allowed (ApplicationNumber , FunctionName, Override)

    Description

    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'.

    Parameters
    Parameter 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.
    Returns

    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

    See Also

    ds_LoginText, ds_SetAccess

    Example
    Example
    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

    ds_ChangeLoginEx

    ds_ChangeLoginEx (ApplicationNumber, [Login], [Password], [Options])

    Description

    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.

    Parameters
    Parameter 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
    Returns

    A Byte containing 0 if the operation was successful, or 1 if the login was unsuccessful.

    Example
    Example
    NewLogin String(12)
    NewPassword String(12)
      Code
      ds_ChangeLoginEx (AppNum,NewLogin,NewPassword)

    See Also

    ds_LoginUser, Code : Change Login, Making your own Secwin windows

    ds_ChangeUserEmailAddress

    ds_ChangeUserEmailAddress (long app,long pUser,string pUserSite,string pPassword,string pEmailAddress,long options)

    Description

    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.

    Parameters
    Parameter 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.
    ds_CannotBeBlank: if added will not change an email address to blank.
    Returns

    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).

    Example
    Example
    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).

    See Also

    ds_LoginUser, ds_GetUserProperty

    ds_ChangePassword

    ds_ChangePassword ()

    Description

    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_ChangePasswordEx function.

    Returns

    Nothing

    Example
    Example
    NewPassword String(20)
    OldPassword String(20)

      Code
      ds_ChangePassword(OldPassword,NewPassword)

    See Also

    ds_ChangePasswordEx, Code : Calling Change Password,Making your own Secwin windows

    ds_ChangePasswordEx

    ds_ChangePasswordEx (AppNum, OldPassword, NewPassword, VerifyPassword, Options)

    Description

    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.

    Parameters
    Parameter 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 DS_DONTWARN: If added, then a message is not displayed with the error
    DS_CASESENSITIVITYOFF: If added, does not save the new password case sensitive

    Returns

    A Byte containing 0 if the operation was successful, or one of the following error codes;

    ds_InvalidPassword: Incorrect Old Password
    ds_CannotBeSame: New password cannot be the same as old password
    ds_PasswordsMustMatch: New Password and Verify Password don't match.
    ds_CannotBeBlank: Password cannot be blank
    ds_CannotBeSimple: Password must contain 6 Alpha and 3 Numeric Characters
    ds_InvalidUser (-100): The user is not yet logged in.

    This last requirement is enforced if the Force Long Password option on the Login extension is set.

    Example
    Example
    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)

    See Also

     ds_LoginUser

    ds_CheckEncryptedActivation

    ds_CheckEncryptedActivationCodeEx (string pActivationCode,*ProductDetailsGroupType pProductDetails,string pSeedCode,long pAppNumber,Queue pLimitsQueue,long pOptions=0),string

    ds_CheckEncryptedActivationCode (string pActivationCode,*ProductDetailsGroupType pProductDetails,string pSeedCode,long pAppNumber,Queue pLimitsQueue),string


    Description

    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.

    Parameters
    Parameter 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.
    Returns

    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).

    Example

    See the ds_GetEncryptedActivationCode example to set the details of the licence. These must match those that are used to generate the activation code.
    Example
      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

    ds_CurrentAppLevel

    ds_CurrentAppLevel ( )

    Description

    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.

    Returns

    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).

    Example
    Example
    Result Long

      Code
      Result = ds_CurrentAppLevel()

    See Also

    Code : Get License Details, Using Levels

    ds_CurrentCopies ( )

    ds_CurrentCopies ( )

    Description

    Allows the programmer to get the number of Copies set in the current license.

    Returns

    A long containing the current number of copies.

    Example
    Example
    Result Long

      Code
      Result = ds_CurrentCopies()

    See Also

    Code : Get License Details, Using Network Copies

    ds_CurrentCounter

    ds_CurrentCounter ( )

    Description

    Allows the programmer to get the Counter set in the current license. This Counter is set when the activation code is generated, and used.

    Returns

    A long containing the current Counter value.

    Example
    Example
    Result Long

      Code
      Result = ds_CurrentCounter()

    See Also

    Code : Get License Details, Using Counters

    ds_GetEncryptedActivationCode

    ds_GetEncryptedActivationCode (long pActivationExpires,long pLicenceExpires,*ProductDetailsGroupType pProductDetails,string pSeedCode,Queue pLimitsQueue),string

    Description

    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.
    Parameters
    Parameter 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 activation 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.
    Returns

    A string containing the activation code to register the application at the clients site (using the ds_CheckEncryptedActivationCode function).

    Example
    Example
    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

    ds_UpdateUser

    ds_UpdateUser (long App,ds_UserDetailsType pUserDetails,long pRequest)

    Description

    Lets you insert a user, change a user's (or user group's) details, or delete a user in source code.

    Note: This function has replaced the superannuated functions: ds_ChangeUser, ds_InsertUser and ds_DeleteUser

    Parameters
    Parameter 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.
    Returns
    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 occurred while trying to save the data changes.
    Example
    Example
    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

    ds_Users

    ds_Users (UserQueue)

    Description

    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.
    This function is included in the docs for backward-compatibility reasons. It should be considered as obsolete. The ds_UsersEx function should be used.


    Parameters
    Parameter 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


    Returns

    Nothing. The queue you passed now contains all the user details.

    Example
    Example
    ds_UserQueue     Queue,pre(_dsq)
    Name                 string(20)
    Surname             string(20)
    Login               string(12)
    UserGroup           Long
                       end

      code
      ds_Users (ds_UserQueue)

    See Also

    ds_InsertUserEx, ds_ChangeUser, ds_DeleteUser, ds_CurrentOperatorNumber

    ds_CountUsers

    ds_CountUsers( SecurityAreaName)

    Description

    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 function needs to be called.

    Parameters
    Parameter 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.
    Returns

    long containing the number of users with Supervisor or Operator access.

    Example
    Example
      code
      if ds_CountUsers(Clip(AppNameDesc) & ' | Main') = 0
        myFirstUser(Clip(AppNameDesc) & ' | Main')
      end

    See Also

    ds_InsertFirstUser

    ds_CreSec

    ds_CreSec

    Description

    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.

    Returns

    Nothing

    Example
    Example
    code
    ds_SetOwner ('bobbybrown', 'washere')
    ds_CreSec( )

    See Also

    Creating the Security File, Activate Security Extension, ds_SetOwner

    ds_Crypt

    ds_Crypt (TextString)

    Description

    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.

    Parameters
    Parameter Type Description
    TextString String This is the string to encrypt or decrypt.
    Returns

    A String containing the encrypted or decrypted string.

    Example
    Example
    Test   String(12)

      Code
      test = ds_Crypt('hello') ! now test contains the encrypted string
      test = ds_Crypt(test) ! now test contains the decrypted string

    ds_ExportTables

    ds_ExportTables(byte pSelectDir=0)

    Description

    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 dssw5.BIN and it will be created in the "Current directory" (unless you using the pSelectDir parameter as directed below). Use the ds_ImportFiles function to import the file.

    Parameters
    Parameter 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.

    Returns

    Nothing

    Example
    Example
    Code
    ds_ExportTables()
    See Also

    ds_ImportTables

    ds_ImportTables

    ds_ImportTables (byte pSelectDir=0)

    Description

    Imports the Secwin tables from a portable format (see ds_ExportTables()). Useful when you need to move the tables from one storage system to another (for example TPS to MSSQL). The encrypted file is probably called dssw5.BIN.

    Parameters
    Parameter 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 before the call to ds_LoginUser (and indeed as soon after the connection to the backend is established as is possible). You must have already called the ds_SetOwner in order to set the internal owner string used by Secwin with the connection to your backend (if required).

    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.

    Returns

    Nothing

    Example
    Example
      Code
      ds_ImportTables()
    See Also

    ds_ExportTables

    ds_CurrentLastPasswordChange

    ds_CurrentLastPasswordChange (ApplicationNumber)

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginText.
    Returns

    A long containing the date of the last password change in a Clarion standard date format.

    Example

    Example
    Result Long

      Code
      Result = ds_CurrentLastPasswordChange(AppNum)
      If Today()-Result > 7
        ds_ChangePassword(AppNum)
      End

    See Also

    ds_ChangePassword

    ds_CurrentLevel

    ds_CurrentLevel (ApplicationNumber)

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginText.
    Returns

    A long containing the level of the user currently logged on. The returned value will be either DS_SUPERVISOR or DS_OPERATOR.

    Example
    Example
    CurrentLevel Long
    CurrentLevelString  string(20)
      Code
      CurrentLevel = ds_CurrentLevel(AppNum)
      case CurrentLevel
      of ds_Supervisor
        CurrentLevelString   = 'Supervisor'
      of ds_Operator
        CurrentLevelString   = 'Operator'
      of ds_NoAccess
        CurrentLevelString   = 'No Access'
      end
    See Also

    ds_CurrentLogin, ds_CurrentName, ds_CurrentOperatorNumber, Code : Calling Current

    ds_GetProperty; ds_GetUserProperty

    ds_GetProperty (long ApplicationNumber,string pUserNumber,<string pUserSite>,string pProperty)

    ds_GetUserProperty (long ApplicationNumber,string pUserLogin,<string pUserSite>,string pProperty)

    Description

    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).

    Parameters
    Parameter 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
    Returns

    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.

    Example
    Example
      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

    ds_SetProperty;ds_SetUserProperty

    ds_SetProperty (long ApplicationNumber,string pUserNumber,<string pUserSite>,string pProperty,string pValue)

    ds_SetUserProperty (long ApplicationNumber,string pUserLogin,<string pUserSite>,string pProperty,string pValue)

    Description

    These function sets information pertaining to a user (or the current user). Depending on the property passed, will depend on the value set (see the pProperty parameter).

    Parameters
    Parameter 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 set:
    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
    pValue String The value to set the property to
    Returns



    Example
    Example
     ds_SetUserProperty(AppNum,Login,,'FirstName','Geoff')

    ds_UserInUserGroup

    ds_UserInUserGroup (long pUser, long pUserGroup)

    Description

    Allows the programmer to check if a user is part of a usergroup.

    Returns

    A long containing 1 (true) if the user is and 0 (false) if not.

    ds_AddUserToUserGroup

    ds_AddUserToUserGroup (long appnum,long pUser,string pUserSite,long pUserGroup,string pUserGroupSite)

    Description

    Allows the programmer to add a user to a usergroup.

    Parameters
    Parameter Type Description
    AppNum Long This is the Application number returned by ds_LoginText.
    pUser long The user number.
    pUserSite string(4) Reserved (leave blank)
    pUserGroup long The user group number
    pUserGroupSite string(4) Reserved (leave blank)
    Returns

    A long containing 0 (no errorcode) if the user is successfully added to the user group or errorcode() if adding the user to the user group failed. Returns 1000 if the user or user group are not valid.

    ds_RemoveUserFromUserGroup

    ds_RemoveUserFromUserGroup (long appnum,long pUser,string pUserSite,long pUserGroup,string pUserGroupSite)

    Description

    Allows the programmer to remove a user from a usergroup.

    Parameters
    Parameter Type Description
    AppNum Long This is the Application number returned by ds_LoginText.
    pUser long The user number.
    pUserSite string(4) Reserved (leave blank)
    pUserGroup long The user group number
    pUserGroupSite string(4) Reserved (leave blank)
    Returns

    A long containing 0 (no errorcode) if the user is successfully removed from the user group or errorcode() if removing the user from the user group failed. Returns 1000 if the user or user group are not valid.

    ds_CurrentExpiryDate

    ds_CurrentExpiryDate ( )

    Description

    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.

    Returns

    A long containing the current date in a Clarion standard date format.

    Example
    Example
    Result Long

      Code
      Result = ds_CurrentExpiryDate()

    See Also

    Code : Get License Details, Using Expiry Dates

    ds_CurrentLicence

    ds_CurrentLicence ( )

    Description

    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.


    Returns

    A string containing the company, or person, name of the registered user. This string can be a maximum of 40 characters long.

    Example
    Example
    result string(40)

      code
      result = ds_CurrentLicence()

    See Also

    Code : Get License Details, Branding on Reports, Branding Using Logo screens

    ds_CurrentLicenceDetailsEx and ds_CurrentLicenceDetails

    ds_CurrentLicenceDetailsEx (*LimitsQueueType pLimitsQueue),string
    ds_CurrentLicenceDetails (),string


    Description

    This function returns all the licence details of the current licence used by the application. The newer ds_CurrentLicenceDetailsEx function also populates the passed pLimitsQueue with the current counter information.

    Parameters (ds_CurrentLicenceDetailsEx only)
    Parameter Type Description
    pLimitsQueue LimitsQueueType A queue containing the description of the counter and it's count:
    LimitsQueueType queue,pre(_dsLQT),type
    Description string(252)
    Limit long
    LimitIsRelative long
    MinLevel long
    MaxLevel long
    ExtraString string(252)
    end

    Returns

    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
    Example
    Example
    LicenceDetails  group(ProductDetailsGroupType),pre(LD) .
    LocLimitsQueue  queue(LimitsQueueType) .

      code
        LicenceDetails = ds_CurrentLicenceDetailsEx()
        message('Current licence details are:|' & |
                ' Company: ' & LD:CompanyName & '|' & |
                ' LicenceType: ' & LD:LicenceType & '|' & |
                ' Copies: ' & LD:Copies & '|' & |
                ' Level: ' & LD:Level & '|' & |
                ' SerialNumber: ' & LD:SerialNumber & '|' & |
                ' Dealer: ' & LD:Dealer)

    ds_CurrentlyLoggedIn

    ds_CurrentlyLoggedIn (Options)

    Description

    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.

    Parameters
    Parameter Type Description
    Options Long Valid options are DS_DONTSHOWSCREEN.

    Returns

    A comma delimited string containing the list of User Names currently on the system.

    Example
    Example
    List string(255)

      Code
      ds_CurrentlyLoggedIn()
      list = ds_CurrentlyLoggedIn (DS_DONTSHOWSCREEN)

    See Also

    Code : Calling Currently Logged In, Using Network Copies, ds_CurrentlyLoggedInEx

    ds_CurrentlyLoggedInEx

    ds_CurrentlyLoggedInEx (LoggedInQueue,long pOptions=0)

    Description

    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.

    Parameters
    Parameter 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...
    pOptions long This is a bit loaded option:
    Bit0 - if set, includes duplicates in the list of users.

    Structure
    Structure
    LoggedInQueue       QUEUE,PRE(_dsqex)
    Name                   STRING(255)
    Reserved               STRING(255)
                        END

    Returns

    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.

    Example

    Example
    UserQueue            QUEUE,PRE(_dsqex)
    Name                   STRING(255)
    Reserved               STRING(255)
                         END
    s                    STRING(255)


      code
      s = ds_CurrentlyLoggedInEx (UserQueue)


    See Also

    Code : Calling Currently Logged In, Using Network Copies, ds_CurrentlyLoggedIn

    ds_CurrentOptional

    ds_CurrentOptional ( )

    Description

    Allows the programmer to get the optional modules that this program has been licensed to as set in the current license.

    Returns

    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.

    Example
    Example
    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.

    See Also

    Code : Get License Details, Using Optional Modules

    ds_CurrentSerialNumber

    ds_CurrentSerialNumber

    Description

    Allows the programmer to get the Serial number as set in the current license.

    Returns

    A String (20) containing the Serial Number.

    Example
    Example
    SerialNumber   String(20)

      code
      SerialNumber = ds_CurrentSerialNumber()

    See Also

    Code : Get License Details

    ds_DecrementCounterEx

    ds_DecrementCounterEx(long pDecrementBy)

    Description

    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.

    Returns

    0 if successful. 1 if failed. The function will fail if the counter is already set to 0.

    Example
    Example
    Result  Long

      Code
      result = ds_DecrementCounterEx(1)
      If result = 0 then return.

    See Also


    Using Counters
    ds_CheckCounter

    ds_CurrentLogin

    ds_CurrentLogin (ApplicationNumber )

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginText.
    Returns

    A string containing the login code of the user currently logged on. The maximum length of the string is 12 characters.

    Example
    Example
    CurrentLogin string(12)

      Code
      CurrentLogin = ds_CurrentLogin (AppNum)

    See Also

    ds_CurrentLevel, ds_CurrentName, ds_CurrentOperatorNumber, Code : Calling Current

    ds_CurrentName

    ds_CurrentName (ApplicationNumber )

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginUser.

    Returns

    A string containing the name of the user currently logged on. The maximum length of the string is 40 characters.

    Example
    Example
    currentname string(40)

      code
      currentname = ds_CurrentName(AppNum)

    See Also

    ds_CurrentLevel, ds_CurrentOperatorNumber, ds_CurrentLogin, Code : Calling Current

    ds_CurrentOperatorNumber

    ds_CurrentOperatorNumber (ApplicationNumber)

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginText.
    Returns

    A long containing the operator number of the user currently logged on.

    Example
    Example
    CurrentOperator Long

      Code
      CurrentLevel = ds_CurrentOperatorNumber(AppNum)

    See Also

    ds_UsersEx, ds_CurrentLevel, ds_CurrentLogin, ds_CurrentName, Code : Calling Current

    ds_CurrentUserGroup

    ds_CurrentUserGroup (ApplicationNumber)

    Description

    This function has been deprecated in Secwin 4 for the following reason:

    In Secwin 3 - you could only assign one user group to a user, but in Secwin 4, you can assign a user to multiple usergroups, so in principle (unless the user is only assigned to one user group) - there cannot be such a thing as a CurrentUserGroup.

    This function has been superceded with a function that returns a queue of usergroups that the user is assigned to:

    secwin.htm#ds_UsersUserGroups

    You'll need to alter your code so that it loops through the UserGroups queue and checks each value to see whether that user belongs to the user group (rather than checking a single value).

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginText.

    ds_CurrentWorkGroupEx

    ds_CurrentWorkGroupEx (ApplicationNumber)

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginText.

    Returns

    A long. The number returned is the number entered in on the User form.

    Example
    Example
    CWG long

      code
      CWG = ds_CurrentWorkGroup (AppNum)

    See Also

    Work Groups, ds_GetWorkGroupEx

    ds_GetAccessEx

    ds_GetAccessEx (ApplicationNumber, CalledBy, User) (or ds_GetAccess4)

    Description

    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.

    The ds_GetAccess4 is used in the GlobalSetAccess window, and will create the access point to an area that the user has not yet accessed (assigning the access point the default access).

    Parameters
    Parameter 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.

    Returns

    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.

    Example

    See the included Splash example for an example of a SetAccess window.

    See Also

    ds_Allowed, ds_SetAccessEx

    ds_CurrentName

    ds_CurrentName (ApplicationNumber )

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginText.

    Returns

    A string containing the name of the user currently logged on. The maximum length of the string is 40 characters.

    Example
    Example
    currentname string(40)

      code
      currentname = ds_CurrentName(AppNum)

    See Also

    ds_CurrentLevel, ds_CurrentOperatorNumber, ds_CurrentLogin, Code : Calling Current

    ds_CheckCounter

    ds_CheckCounter (string pCounter,long pDecrementBy=0,long pOptions=0),long

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    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.

    Example
    Example
    Result  Long

      Code
      result = ds_CheckCounter ('WagesReports',1)
      If result = 0 then return.

    See Also

    Using Counters

    ds_DeleteUser

    ds_DeleteUser (ApplicationNumber , Login)

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginUser.
    Login String The login code of the operator being deleted.

    Returns

    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.

    Example
    Example
      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

    See Also

    ds_InsertUserEx, ds_ChangeUser

    ds_GetAccess44

    ds_GetAccess44 (long App,string CalledBy,Long User,string pUserSite)

    Description

    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.

    Parameters
    Parameter 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).

    Returns

    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.

    Example
    Example
    if ds_GetAccess4(App,'Level',UserNumber,'$$$$') = DS_OPERATORString then
      !Do stuff for operators in here.
    end
    Access = ds_GetAccess4(App,CalledBy,UserNumber,'$$$$')
    See Also

    ds_UserAllowed, ds_ModifyAccessEx

    ds_GenerateActivationCode

    ds_GenerateActivationCode ( )

    Description

    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.

    Returns

    Nothing

    Example
    Example
      code
      ds_GenerateActivationCode()

    See Also

    ds_GetActivationCode, Some Activation Code Secrets

    ds_GetActivationCode

    ds_GetActivationCode ( Product, Company, SerialNumber, Copies, Level, Optional, ExpiryDate, Counter, SeedCode )

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    A String of length 20 containing the Activation code.

    Example
    Example
    AC String(20)
      Code
      AC = ds_GetActivationCode ('App','Comp','001',5,3,0,today()+30,0,1234)

    See Also

    ds_GenerateActivationCode, Some Activation Code Secrets

    ds_GetDriveSerialNumber

    ds_GetDriveSerialNumber ( [Drive] )

    Description

    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.

    NOTE: You will only be able to get a local drive's serial number. If your application uses data from a network drive, then you will not be able to get that drive's serial number (across a LAN). In this case (if you still require the drive serial number, in spite of not being able to use it for the licence), you must specify the local drive in the Drive parameter, otherwise the function will always return 0 

    Parameters
    Parameter Type Description
    Drive String Optional. Contains the Root directory of the drive to check. If omitted then the Current Path will be used.

    Returns

    Ulong containing the Serial Number

    Example
    Example
    Code
    If ds_GetDriveSerialNumber() <> ds_CurrentSerialNumber()
       message('I'm an unhappy program.')
       return
    End

    ds_GetWorkGroup

    ds_GetWorkGroup (ApplicationNumber, OperatorNumber)

    Obsolete.

    Use ds_GetWorkGroupEx instead. ds_GetWorkGroup returns a Short not a Long.

    ds_GetWorkGroupEx

    ds_GetWorkGroupEx (ApplicationNumber, OperatorNumber)

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    A long. The number returned is the number entered in on the User form.

    Example
    Example
    CWG short

      code
      CWG = ds_GetWorkGroup (AppNum,1)

    See Also

    Work Groups

    ds_InsertFirstUser

    ds_InsertFirstUser(SecurityAreaName,Firstname,Lastname,LoginCode,Number)

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    0 = Success. Otherwise Failure.

    Example
    Example
      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

    See Also

    ds_CountUsers

    ds_InsertUser

    ds_InsertUser( AppNum, FirstName, LastName, LoginCode, InitialAccess, Workgroup, Level)

    Description

    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.

    ds_InsertUserEx

    ds_InsertUserEx( AppNum, FirstName, LastName, LoginCode, InitialAccess, Workgroup, Level, UserGroup)

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    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)

    Example
    Example
    Code
    ds_InsertUserEx (AppNum, 'Bill', 'Gates', 'BG',1,0,DS_OPERATOR,0)
    ds_InsertUserEx (AppNum, 'Sales', ' Sales','',1,0,DS_OPERATOR,-1)

    See Also

    ds_UsersEx, ds_ChangeUser, ds_DeleteUser

    ds_LicenceOk

    ds_LicenceOk( RqdLevel, RqdModules, Options)

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    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 dssw5 file goes backwards. (suppress this check with DS_MULTIDATA)

    Example
    Example
    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)

    ds_LockScreen

    ds_LockScreen ( ApplicationNumber )

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginUser.

    Returns

    Nothing

    Example
    Example
    Code
    ds_LockScreen (AppNum)

    See Also

    Ancillary User Functions, Code : Calling Lock Screen

    ds_LoginUser

    ds_LoginUser (ds_UserLoginOptions pUserLoginOptions,*long pUser) (replaces the old ds_LoginText function)


    Possible Options

    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.

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    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.

    Advanced

    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.

    Example
    Example
    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'
         !+ds_UseUserAuthentication to use user authentication to login
         !+DS_USECURRENTLOGON to use a login from another area/exe
         !+DS_CASESENSITIVITYOFF to use a case insensitive password when logging in
      MyUserLoginOptions.Options = 0   !Use the equates listed above.
      AppNum = ds_LoginUser (MyUserLoginOptions , MyUser)
      if AppNum = 0
        ! login was unsuccessful
        return
      End

    See Also

    ds_Logout, Extension : User Login Here, Login and Password Access Control, Making your own Secwin windows

    ds_LogoutUser

    ds_LogoutUser (long ApplicationNumber,long pUser)

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    0 if successful. 1 if unsuccessful.
    If the function returns 1, then the user was not logged in to the application.

    Example
    Example
    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

    See Also

    ds_LoginUser

    ds_OperatorBrowse

    ds_OperatorBrowse (ApplicationNumber)

    Description

    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.

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginUser.

    Returns

    Nothing

    Example
    Example
    AppNum long

    code
    ds_OperatorBrowse (AppNum)

    See Also

    Operator Browse and Form, User Groups, Work Groups

    ds_RegisterProductEx

    ds_RegisterProductEx ( Product, Seed, Options, Company, SerialNumber, Copies, Level, Modules, Activation code, Counter)

    Description

    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.

    Parameters

    Parameter 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.

    Returns

    0 if successful, 1 if Invalid Activation code.

    Example

    code
    ds_RegisterProduct('Wonderprog',12345678,0)
    ds_RegisterProduct('Wonderprog',12345678,DS_LVL4+LVL5)
    ds_RegisterProduct('Wonderprog',12345678,DS_LVL4+LVL5+DS_OM15)


    See Also

    Code : Calling Register Product, Overview of Licensing, Making your own Secwin Windows

    ds_UserRun

    ds_UserRun (long ApplicationNumber,long pUser)

    Description

    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".

    Parameters
    Parameter Type Description
    ApplicationNumber Long This is the Application number returned by ds_LoginUser.
    pUser Long The user's login number.

    Returns

    A string which needs to be included as a parameter in the Clarion "Run" statement.

    Example
    Example
    code
      run ('ProgName ProgParam ' & ds_Run (AppNum))

    See Also

    Code : Run Another Exe, Secwin Examples

    ds_LoadLicenceFromXML

    ds_LoadLicenceFromXML(*ProductDetailsGroupType pDetailsGroup,*queue pLimitsQueue,string pXMLFile,<long pXMLStringLen>),long

    Description

    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).

    Parameters
    Parameter 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.

    Returns

    long - 0 for success, otherwise an error occurred.

    Example
    Example
    YourXMLString   string(xxxx)
    YourXMLStringLen    long
      code

          !Here's an example of how you would create an XML licence string:
          !YourXMLString contains the licence details in an XML formatted string.
        if ds_LoadLicenceFromXML(REG:CodeGroup,Queue:Browse,YourXMLString,YourXMLStringLen) .

          !Here's an example of how you would create an XML licence file:
        if ds_LoadLicenceFromXML(REG:CodeGroup,Queue:Browse,clip(REG:CompanyName) & '_' & clip(REG:Product) &'.xml') .
    See

    Secwin Data Types

    ds_SaveLicenceToXML

    ds_SaveLicenceToXML (*ProductDetailsGroupType pDetailsGroup,*queue pLimitsQueue,<string pXMLFile>,<ds_SecwinXMLString pSecwinXMlString>,<SaveLicenceToXMLOptionsGroupType pOptions>),long

    Description

    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)

    Parameters
    Parameter 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'.

    Returns

    long - 0 for success, otherwise an error occurred.

    Example
    Example
    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 also

    Secwin Data Types ; ds_MakeValidFileName

    ds_MakeValidFileName

    ds_MakeValidFileName (string pfileName)

    Description

    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.

    Parameters
    Parameter Type Description
    pfileName string The name of the file that must be stripped of it's invalid characters.
    Returns

    string - contains the pFileName with invalid dos filename characters replaced with '_'

    Example
    Example
    if ds_SaveLicenceToXML(REG:CodeGroup,Queue:Browse,ds_MakeValidFileName(clip(REG:CompanyName) & '_' & clip(REG:Product) &'.xml')) .
    See Secwin Data Types ; ds_SaveLicenceToXML

    ds_SecwinMakeover

    ds_SecwinMakeover (MakeoverObject)

    Description

    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.

    Parameters
    Parameter Type Description
    MakeoverObject Makeover A reference to a Makeover objected created in the Exe. This would typically be ThisMakeover

    Returns

    Nothing

    Example
    Example
    code
      ds_SecWinMakeover(ThisMakeover)

    ds_SecwinMessage

    ds_SecwinMessage (MessageName)

    Description

    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
    Parameters
    Parameter Type Description
    MessageName String This is one of the Standard Secwin Message Names.

    Returns

    Nothing

    Example
    Example
    code
      ds_SecWinMessage('AccessRestricted')

    ds_ModifyAccessEx

    ds_ModifyAccessEx (ApplicationNumber ,ScreenName, Options)

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    Nothing

    Example
    Example
    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

    See Also

    Set Access Rights Screen

    ds_SetAccess

    ds_SetAccess (ApplicationNumber ,ScreenName, Options)

    Description

    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.

    Parameters

    Parameter 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.

    Returns

    Nothing

    Example
    Example
    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

    See Also

    Set Access Rights Screen

    ds_SetAccessEx

    ds_SetAccessEx (ApplicationNumber, CalledBy, User, Rights )

    Description

    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.

    Parameters
    Parameter 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

    Returns

    Nothing

    Example

    See the included Splash example for an example of a SetAccess window.

    See Also


    ds_Allowed, ds_GetAccessEx

    ds_ModifyAccessEx

    ds_ModifyAccessEx (long App,string CalledBy,Long User,string UserSite,string Rights,long pOperation=ds_ReplaceExistingAccess,long pAccessIsString=0)

    Description

    This function sets the access rights for a particular user, for a particular procedure in the application.

    Parameters
    Parameter 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 (dependent 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).

    Returns

    Nothing

    Example
    Example
    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.

    See Also

    ds_UserAllowed, ds_GetAccess4

    ds_SetDefaultFontEx

    ds_SetDefaultFontEx(Face, Size, Color, Style, CharSet)

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    Nothing

    Example
    Example
    code
    ds_SetDefaultFont('Arial',10,Color:Black,Font:Regular)

    See Also

    Extension : User Login Here

    ds_SetLanguage

    ds_SetLanguage (LanguageFileName)

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    Nothing

    See Also

    User Guide : Internationalization support

    Example
    Example
    AppNum long

    code
    ds_SetLanguage ('Spanish.Irf')

    See Also

    Code : Calling Set Language, Translating Secwin Windows

    ds_SetLogo

    ds_SetLogo (LogoFileName, CallbackFunctionAddress)

    Description

    Allows you to change the logo that appears on all of the Secwin screens.

    Parameters
    Parameter 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.

    Returns

    Nothing

    Example
    Example
    code
    ds_SetLogo('c:\logo.ico',0) ! use logo in root directory
    ds_SetLogo('logo.ico',0) ! use logo in current directory

    See Also

    Changing The Logo

    ds_SetOwner

    ds_SetOwner (string Owner1, string Owner2)

    Description

    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.

    Parameters
    Parameter Type Description
    Owner1 String This is the Owner attribute of the Security files. (dssw5)
    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.

    Returns

    Nothing

    Example
    Example
    code
    ds_SetOwner ('bobbybrown','washere')   !For flat files
    ds_SetOwner ('SQLConnection,SQLDataBase,SQLUser,SQLPassword','/MultipleActiveResultSets=1')   !For SQL files

    See Also

    ds_CreSec, Activate Secwin Extension

    ds_SetPath

    ds_SetPath ([Path], [LanguageFile], [LanguagePath])

    Description

    Allows you to programmatically set the location of the Secwin support files, including the dssw5 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 (i.e. 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

    Parameters
    Parameter Type Description
    Path String A specific path where the dssw5 file can be found.
    LanguageFile String A specific name for the language file to use.
    LanguagePath String A specific path for the language file.

    Returns

    Nothing

    Example
    Example
    code
    ds_SetPath('c:\')
    ds_SetPath('HERE')
    ds_SetPath('HERE','Dutch.Irf','EXEDIR')

    See Also

    Translating Secwin Windows

    ds_SetPin

    ds_SetPin (SecurityAreaName, PinNumber)

    Description

    Used to stamp the dssw5 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.

    Parameters
    Parameter 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.

    Returns

    Nothing

    Example
    Example
    code
    ds_SetPin('Bobs App',12345678)

    See Also

    ds_UsePin, Pin Numbers, Extension : Activate Secwin Features

    ds_SetSuperUser

    ds_SetSuperUser (LoginCode)

    Description

    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.

    Parameters
    Parameter Type Description
    LoginCode String This is the Login Code of the user to make a Super User

    Returns

    Nothing

    Example
    Example
    code
    ds_SetSuperUser ('demo')

    See Also

    ds_UsersEx, ds_InsertUserEx, ds_ChangeUser, ds_DeleteUser, Extension : User Login Here, Super Users

    ds_UseLicence

    ds_UseLicence (ProductName, ApplicationNumber,LicenseName, Options)

    Description

    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.

    Parameters
    Parameter 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.

    Returns

    Nothing

    Example
    Example
    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)

    See Also

    Overview of Licensing

    ds_UsePin

    ds_UsePin (SecurityAreaName,AppPinNumber)

    Description

    This function allows you to "stamp" a dssw5 file as being valid. Without a pin number the user can simply delete the dssw5 file, and re-create an empty one using CRESEC25. This use of Pin numbers requires however that the dssw5 file be stamped with the correct pin number before it will be considered valid.

    Parameters
    Parameter 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 dssw5 files containing this pin number will be valid.

    Returns

    Nothing

    Example
    Example
    code
    ds_UsePin (AppNameDesc,12345678)
    ds_LoginUser( AppNameDesc, ds_Default,'','')

    See Also

    ds_SetPin, Pin Numbers, Extension: Activate Secwin Features

    ds_UsersEx

    ds_UsersEx (Appnum,UserQueueEx)

    Description

    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.

    Parameters
    Parameter Type Description
    AppNum Long This is the Application number returned by ds_LoginUser.
    This setting is only needed if the Workgroup field needs to be populated. Setting this to 0 does not fetch the Workgroup (or UserGroup) fields from other tables and so imparts a small performance benefit.
    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.

    Structure

    ds_UserQueueEx       QUEUE,PRE(_dsqex)
    Name                   STRING(40)
    Surname                STRING(40)
    Login                  STRING(128)
    UserGroup              LONG         
    ! obsolete, only set if appnum is passed
    Number                 LONG
    LastPasswordChangeDate LONG
    Workgroup              LONG         
    ! only set if appnum is passed
    Reserved2              STRING(12)
    Reserved3              STRING(20)
                         end


    Returns

    Nothing. The queue you passed now contains all the user details.

    Example
    Example
    ds_UserQueueEx       QUEUE,PRE(_dsqex)
    Name                   STRING(40)
    Surname                STRING(40)
    Login                  STRING(128)
    UserGroup              LONG
    Number                 LONG
    LastPasswordChangeDate LONG
    Workgroup              LONG
    Reserved2              STRING(12)
    Reserved3              STRING(20)
                         end


      code
      ds_Users (Appnum,ds_UserQueueEx)

    See Also

    ds_UpdateUser, ds_UsersUserGroups

    ds_UpdateUsersUserGroups

    ds_UpdateUsersUserGroups (long pAppNum,long pUser,string pUserSite,ds_UsersUserGroupsQType pUserGroupsQu,long pForce=0),long

    Description

    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 compare the flags to see where the changes have occurred (rather than applying a change to every record that is in the queue - which is really inefficient).

    Parameters
    Parameter 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.
    Returns

    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).

    Example code
    Example
    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 
    See also

    ds_UsersUserGroups , ds_GetUserProperty

    ds_UsersUserGroups

    ds_UsersUserGroups (long AppNum,long pUser,string pUserSite,ds_UsersUserGroupsQType pUGQueue,long pOptions=1,<*string pChangeAccess>,long pHash=0),long

    Description

    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.

    Parameters
    Parameter 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)
    Structure

    ds_UserSUserGroups       QUEUE(ds_UsersUserGroupsQType ),pre(UUG) .   !You must have a prefix - otherwise you'll get compile warnings on this line

    Returns

    The number of usergroups that the user belongs to.

    Example
    Example
         !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

    ds_ResetUserPassword

    ds_ResetUserPassword(long pUser,string pUserSite),long

    Description

    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)

    Parameters
    Parameter 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).
    Returns

    A long indicating pass (0) or failure (non-zero).

    Example
    Example
    ReturnValue            long
      code
        ReturnValue            = ds_ResetUserPassword(MyUser,'')
    See also

    ds_SetEncryptionKey. To get the user number, use the ds_GetUserProperty function.

    ds_SetEncryptionKey

    ds_SetEncryptionKey(string pEncryptionKey)

    Description

    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.

    Parameters
    Parameter Type Description
    pEncryptionKey string This is the unique encryption key to use for your application to access the operator's table.
    Returns

    Nothing

    Example
    Example
    ReturnValue            long
      code
        ds_SetEncryptionKey('MyEncryptionKey')
    See also

    ds_ResetUserPassword

    Secwin Data Types

    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\accessory\libsrc\win 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)

    Installation

    Run the Supplied Installation file.

    Distribution

    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 Clarion 7.3-8
    Topspeed Driver S6TPSX.DLL S55TPSX.DLL S70TPS.DLL SLATPS.DLL
    Btrieve Driver S6BTRX.DLL S55BTRX.DLL S70BTR.DLL SLABTR.DLL
    SQL Anywhere Driver S6SQAX.DLL S55SQAX.DLL S70SQA.DLL SLASQA.DLL
    MsSQL Driver S6MSSX.DLL S55MSSX.DLL S70MSS.DLL SLAMSS.DLL
    ODBC Driver S6ODBCX.DLL S55ODBCX.DLL S70ODB.DLL SLAODB.DLL
    IPDriver s6IPDx.DLL


    Pervasive SQL Driver s6SCAx.DLL s55SCAx.DLL s70SCA.DLL sLASCA.DLL

    License & Copyright

    All the files distributed as part of the Secwin package are copyrighted and remain the property of CapeSoft Software.

    Secwin is licensed per developer. In other words each developer can use Secwin on more than one machine (Work, Laptop, Home etc.) - however each developer requires his own copy of Secwin.

    Limitation of Liability

    CapeSoft Software Ltd and its employees assume no liability for the use of this package. Our sole liability rests with fixing any software errors that may exist in the distributed Secwin files. In certain cases, due to bugs in software supplied to us, it may be impossible to correct errors in Secwin. Use of this product implies acceptance of this limitation.

    FAQs

    I'm getting Runtime and/or Compile Errors

    NetTalk WebServer Questions

    How do I add Secwin user access to my NetTalk WebServer application?
    I want to allow users to self-insert, but need to check that they're already added to a customers table
    After creating my supervisor and a user, none of my set access windows show the user
    I need to create a SetAccess menu item for a "window" that does not have a security icon
    I've followed the steps, but cannot add a user or reset the password
    I don't want to store the email server settings in the INI file
    I'm not able to add users as my Exchange server is not allowing test emails through.
    Where is the data stored (from the IMDD tables I imported into my dct)?
    I want to run some code after a successful login. Where do I put this?
    Combining procedures' security access settings into one
    My SetAccess procedure comes up with No Records. Everything else seems to work
    I upgraded to NetTalk 7 and now I can no longer login to my applications

    Licensing Questions

    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 dssw5.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?
    1.15. I'm creating an upgrade for my product, so I want my program to require a new licence, but it must be primed with the old licence details.
    1.16. After licencing a customer with x counter, I want to issue a new licence and increment the counter. How do I do this?
    1.17. I want to use the record counting feature to limit uses, but I need to write my own code to check the number of records. How do I do this?

    User Security Questions

    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?
    2.5. Is there any way to include an option in Secwin 6 to allow for the user to be forced to change their password at their initial login?

    Access Control Questions

    3.1. Can I see who is logged into the program on all the clients? See the ds_CurrentlyLoggedInEx function
    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?
    3.21. I just want to use windows authentication, how do I set this up for a new user?
    3.22. What protocol does windows authentication use?

    Registration Questions

    4.1. My Text for Cut and Paste has an incorrect CRC check in the Activation code. What must I do?
    4.2. When I try to drag and drop a licence file into my application in Windows 7 it does not do anything.

    General Template Questions

    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?

    General Questions

    6.1. How can I rename the dssw5.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
    6.8. What DLLs and file do I need to ship with my application?
    6.9. I get a lot of flickering on my controls that are Secwin controlled. How do eliminate this?

    Upgrading Questions

    7.1. Why should I upgrade from Secwin 3/4 to Secwin 6?
    7.2. What must I change in my app when I upgrade from Secwin 3/4 to Secwin 4/6?
    7.3. How do I upgrade from Secwin 3/4 to Secwin 6?
    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 4 to Secwin 6?
    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 3 to Secwin 4/6, none of my users can log in.
    7.8. Can I upgrade from Secwin 3 to Secwin 6?
    7.9. What happened to Secwin 5?

    0.1. Question: I want to allow users to self-insert, but need to check that they're already added to a customers table

    Answer: In your SecwinWebLoginForm, use the following embeds:


    In the Secwin_ValidateEmailAddress routine, you can put code to check after the user has entered their email address and verify the email. Here is an example:

    MAI:MailBoxAddress = loc:email         <-----  the email address field in your customers table
    if access:MailBoxes.fetch(MAI:EmailAddressKey)         <----- fetch from the customers table
      loc:invalid = 'email2'
      loc:alert = 'There is no email address in the database that matches. Try again.'
      p_web.ssv('Loc:ValidEmailAddress',Loc:ValidEmailAddress)
      p_web.ssv('SecwinSetEmailEntryCount',p_web.gsv('SecwinSetEmailEntryCount') + 1)
      exit
    end


    0.2. Question: After creating my supervisor and a user, none of my set access windows show the user.

    Answer:
    By default, a new self-created user gets assigned to usergroup 2. If you have not created the user group yet, then the created user will be associated with a non-existant user group. You must first add the user group (delete created users except the supervisor) and add the user group. To do this, login as the supervisor, and via the web menu user groups browse add the default user group.

    If you want to programmatically add this usergroup, then you need to do this in the WebServer procedure (where you added the User Login Here extension template). After the ds_ChangeUserPassword function call, add the following code (see the example for more detail):

    if ds_InsertUserEx(AppNum,'Basic User Group','Basic User Group','Basic User Group',ds_NoAccess,0,ds_Operator,-1)
      !Now we create the user group for the users to belong to.
    end

    0.3. Question: I need to create a SetAccess menu item for a "window" that does not have a security icon

    Answer:
    Go to the Procedure that contains the menu. This is usually PageHeaderTag. Go to the Web Menu Extension. Select the 'Security' Menu item and click Properties.

    NOTE: The SetMenuAccess item has a Procedure name set to 'SecwinWebUserAccess' and the parameters '_Screen_=MainMenu' where MainMenu is the name of the screen (or Secwin friendly screen name if overridden).



    For Menus on a NetWebSource page, you need to setup the access controls and groups on the Web Menu Extension, and then the Security tab on the procedure properties of the NetWebSource procedure:



    NOTE: For Frame web apps, you must add the target frame for the Secwin procedures too (normally this would be 'right_fram').

    0.4. Question: I've followed the steps, but cannot add a user or reset the password

    Answer:
    Make sure that you've entered all the necessary Email info into your settings file. The GetSettings procedure is used to extract the following settings:

    [ApplicationSettings]
    EmailServer=192.168.xx.xx
    EmailPort=25
    FromAddress=test@capesoft.com
    HostAddress=http://127.0.0.1:88       !This is the address the user would type in the browser to get to your site.
    EmailAuthUser=
    EmailAuthPassword=


    If you're using authenticated email, then you'll need a user and password for that account.

    If you're using Exchange server as your email server, you may have some rules set about internal email addresses. Some users have struggled in testing because of Exchange server blocking some emails addressed to test users.

    If you imported the SecwinWeb procedures prior to 6.06, then the user's login must match the email address. If you want to support other login names, then you need to re-import the secwin web procedures (or more specifically the SecwinWebCreateUser procedure).

    0.5. Question:
    I don't want to store the email server settings in the INI file

    Answer:
    This is recommended that you change the GetSetting procedure to store the settings in a more suitable place. One of the procedures imported into your application is the GetSetting procedure, and coded as follows:

    ReturnValue = getini('web31Settings',Setting,'@@@NovalueYet@@@','.\Settings.ini')
    if ReturnValue = '@@@NovalueYet@@@'
      putini('web31Settings',Setting,pDefaultValue,'.\Settings.ini')
      ReturnValue = pDefaultValue
    end
    return ReturnValue

    Simply change the getini and putini with a file fetch and update (or getreg and putreg) to change the storage method.


    0.6. Question:
    I'm not able to add users as my Exchange server is not allowing test emails through.

    Answer: If you do not have access to a different Email Server that you can control, you should setup a test domain with someone like gmail (where you can setup email domains for free). This will enable you to setup mail boxes without the rules of Email Server and your NTWS application does not have to send mails via your exchange server. See http://paulstamatiou.com/how-to-setup-gmail-for-hosted-domains for details.



    0.7. Question:
    Where is the data stored (from the IMDD tables I imported into my dct)?

    Answer:
    These are just temporary tables reflecting what’s in the secwin files. The secwin files (for tps that would be the dssw5.tps file) would be ultimately stored in the backend that you stipulate in the Secwin global extension (files tab). The IMDD tables are merely there because NetTalk webserver cannot support queues, otherwise we’d use queues like in the desktop application (for browsing users, access settings, etc.). The tables (whether tps or IMDD) that you imported into your dct are merely temporary tables, and are discarded between sessions as they only reflect the data in the actual secwin files.


    0.8. Question:
    I want to run some code after a successful login. Where do I put this?

    Answer:
    In your SecwinWebLoginForm, you'll find a validateUpdate routine. In that routine, there is an embed point:

    ! Secwin - After LoginUser Success

    Place your code in there to run upon a successful login.


    0.9. Question: Combining procedures' security access settings into one procedure

    Answer:
    Many times you may have a browse on a form (for example if you have a number of buttons or filter options relating to the browse). In this case, the browse would be the child procedure, and you'd probably want only one place to set the security access settings for each user, rather than having 2 places where the supervisor needs to set the same access settings - both in the browse and in the form - for "one screen". In this case, you need to set both the Secwin Friendly Name fields the same in both procedures:



    and in the browse (which would normally be the child procedure), check the Secwin Access Groups are not created here checkbox on the Browse procedure:



    You must then add each of the browse's access groups used to the Secwin Access Groups list in the form procedure:



    It's a good idea to add the groups first to the form procedure, so you can get the Access Control group Number to use in the browse's controls you want to protect. So in the above instance, we set the Insert control on the browse to use Access Control Group 1, and Change control would use Access Control Group 2:



    0.10. Question:
    My SetAccess procedure comes up with No Records. Everything else seems to work.

    Answer:
    In NetTalk 6.38, the sessionID changed from a long to a string. This means that you need to change your sessionID (where used) in your dictionary to a string(255) as well. For your Secwin table, this must be changed as follows:



    NOTE: If you are using a real disk file (as apposed to a memory file) for the temporary secwin tables, then you'll need to either delete the table or at least convert it (using FM3) in order to avoid errorcode 47.

    Next thing you need to do, is open your NTWS application in the IDE, and add quotes to the filter as follows:



    0.11 Question:
    I upgraded to NetTalk 7 and now I can no longer login to my applications

    Answer:
    In your WebServer procedure, go to the Security tab on the Settings tab of the NetTalk or NetSimple Object local extension template's prompts, and uncheck the "Delete Session on Logout".



    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 dssw5.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 dssw5.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 dssw5.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 dssw5.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 dssw5 file in a safe place, so you have a copy for the future. This "virgin" dssw5 file is the one you ship.
    g) Back to the app, turn licensing back on. Compile. Ship (make sure you include the dssw5.tps file that you created earlier in your install). In your install, make sure that you don't overwrite the dssw5.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. Make sure that your seedcode and product is entered correctly in the Register application (in
      the product details) - exactly as it matches in the Secwin Global Extension Licence settings of your application. you can check the 'Warn for wrong product (for testing only)' on the Register Product Controls template - which will give you a warning if the product does not match. You should not release your product with this checkbox checked, as this weakens the security of your product's licence.
    2. Ensure that your are using the latest register application to generate activation codes. If you are forcing the dealer string to be (either included or excluded) in the activation code - then make sure that you do this in both the register application and the template setting in your application (see Creating your own Product Registration window for more details). The best is to leave the template setting to 'Detect in XML' - which means you only need to set this once in the registration server (rather than having to match the child to the server).
    3. If you have hidden fields (or deleted fields) - those fields may contain different values to the ones used by the program generating the registration codes. Unhide those fields (or re-import the SecwinRegisterProduct window) and verify those fields are correct. You can prime them with the default values that are used in the registration program as well. Note: If you are allowing your users to manually enter their details in the RegisterProduct window, then you must make sure they enter all the fields that are used in the Register application to generate the activation code. If you don't want them to see some of the options, then you can hide these (for example the Site, Copies or LicenceType fields), but you must equate them in the PrimeFields embed routine.

      SecLoc:SiteLimiter = '$$$$'
      SecLoc:LicenceType = 1
      SecLoc:Copies = 1

    4. If you are using a new version of the register application, with an old version of your application, then check out: FAQ 1.14

    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. Your Licence Name (set in the Secwin global extension template must match the name used in the Registerabc application exactly) doesn't matche the one used in the register app. Case sensitive inclusive.
    2. Your License Seed Code does not match (between the registerabc application and your own application).
    3. Your Dealer is not being set (in the register application) - and your application is set to force the Dealer code to be set. (See Dealer field in the licence template prompt on your Control_RegisterProduct template on the Secwin Register Product window).
    4. You have completed all the steps of the JumpStart, particularly adding the User Login Here to the frame (or the main window of your application).

    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. That the licence that they're using allows 5 concurrent users.
    2. It could be that your application is still running in memory somewhere - so the .lic files are still opened by those instances. A good way of testing
      for this is to kick everyone out and then delete all the .lic files in the directory where they're set to be (probably with the dssw5.tps file). If some of the instances of the .lic file cannot be deleted (because of in-use) then you've got an app open somewhere using those files. You'll need to use a network tool to determine which PCs have those

    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) .


    1.15. Question:
    I'm creating an upgrade for my product, so I want my program to require a new licence, but it must be primed with the old licence details.

    Answer:
    In your SecwinRegisterProduct window, go to the Secwin's Register Product Controls template prompts. On the Old Licences tab you can enter the names of the previous product names to search for in the licence file:



    If you have upgraded from Secwin 3 on one of these releases, then you will need to convert your counter to the new label. To do this, open your SecwinRegisterProduct source in the embeditor, and find the CopyOldCountersToNew routine, you need to move the old counter as follows:

    case SecLocTemp:OldLicence
    of 'TNA2000'
    orof 'TNA4'
    orof 'TNA5'
          !This is just in here for old versions of TNA (prior to Secwin 5 implementation)
      if records(LimitsQTemp)
        get(LimitsQTemp,1)
        if upper(LimitsQTemp.Description) = 'DEFAULT COUNTER'
          LimitsQTemp.Description = 'Employees'                
    !NOTE: this is the name of the counter you are changing to.
          put(LimitsQTemp)
          debugview('Changed limit to: ' & LimitsQTemp.Description)
        end
      end
      SecLoc:AdditionalString1 = ''
    end


    1.16. Question: After licencing a customer with x counter, I want to issue a new licence and increment the counter. How do I do this?

    Answer:
    When you create the product in the secwin register program, you need to enter the counter name and the default counter limit (which is auto-set when a new licence is created in the secwin register program). This counter name must match the table name for the limit in your application. In this case, don’t make the counter relative.

    When you create the licence in the secwin register program for that customer, it will default to the default counter limit (as above). You can ship that licence to the client (using the XML file). When they want to up the employee limit, then edit their licence in the register program, and up the counter limit to the next limit. Then ship the licence (xml file) with the updated details to the client for them to use re-register the product.

    1.17. Question:
    I want to use the record counting feature to limit uses, but I need to write my own code to check the number of records. How do I do this?

    Answer:
    You can use the embed point Global Objects | CapeSoft Objects | ThisSecwinThreadedClass | CheckRecords | CODE | Check Max Records (database driver). Your code would typically look like this:

    if CheckRecords(pFile) => ds_TableMaxRecords(TableName)  !CheckRecords would be your function that takes a file handle.
      ReturnValue = 0
    end


    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 dssw5 file. And the "install" of the update is overwriting the existing dssw5 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 dssw5.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?

    Answer:
    Typically you would restrict the control that is actually calling the Report (like if it was on the frame, then you would disable this report from there). Otherwise (if your report is being called from a bunch of places and you want to cover your bases) look at the examples\secwin\abc.app you will see a similar type of example (for restricting a report). In your case, what you could do is disable the Start/Pause button so the illegal entrant can only press the cancel button.

    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).

    2.5. Question:
    Is there any way to include an option in Secwin 6 to allow for the user to be forced to change their password at their initial login?

    Answer:
    There are 2 ways of doing it. You can either, immediately after successful login, test if the login and password are the same (using the variables in the login window), and then force a change password. Or you can test the LastPasswordChangeDate (see ds_GetProperty) after successful login. It will be set to 0 when the user is created.

    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:
     You can use ds_UserEx to return the number of users existing. You can use ds_CurrentLevel and then disable the Operator radio button/level.

    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:
    You can do this by creating your own login window (check out the MakingYourOwnSecwinWindows section of the docs) And then handcoding in the OK button's accept:

    if ds_LoginUser(Parameters required )
      if GLO:Password = GLO:Login
        ChangePasswordRtn()                      <---- your procedure to change the password.
      end
    else
       !Login failed
     return
    end

    Check out the ds_ChangePasswordExsection of the docs for more details.

    3.7.Question: How can I set the default access to all access when adding an operator in a Multi-EXE scenario?

    Answer: The only way to do this is to make sure that the Unique Application Name (in the Secwin Global Extension template) and the Unique Area Name (in the Secwin User_Login_Here template) matches in all the applications. It would constitute a major security breach to assign a user access to all applications using the current Security Tables (for applications that have a different Unique Application Name and/or Unique Area Name).

    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 category 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:
    1. Decide how you will limit the records that the user sees (for example: will he only see the records that he has created - will supervisors see everything? etc)
    2. Create a variable to store the current user in and set the user in the ThisWindow.init method:

      Loc:UserNumber = ds_GetProperty(AppNum,,,'Number')
      Loc:UserLevel = ds_GetProperty(AppNum,,,'Level')
    3. Use this in your filter to filter the records shown. Example:

      PRE:UserNumber = Loc:UserNumber or Loc:UserLevel = ds_Supervisor
    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:

    Send To Access Window screenshot

    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:
    In your SecwinOperatorForm procedure, add the following line of code at the end of the LoadRecord Routine (or re-import the Secwin windows using the template utility):   SecLocLDG:InitialAccess = ds_GetProperty(App,SecLocLDG:Number,,'DEFAULTACCESS')

    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?

    Answer:
    This would be an access security hole. If you have a user group for the accounts dept - and you have a user group for the stock control dept. Obviously both areas will have different supervisors. Indeed the one supervisor may not have access to the other area. If the stock control dept supervisor can turn the accounts dept user group to an operator (in his area) - he can then assign people to that user group, hence giving him control over the accounts dept. User groups can only be operators to one security area - and the rest of the areas must be NoAccess.

    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.

    3.21. Question: I just want to use windows authentication, how do I set this up for a new user and what happens if the user does not have a password?

    Answer: Each Secwin user, including the first user to login, must be added to the Secwin users in the normal way (by the first user creating himself, and subsequently the first user, i.e. the supervisor, creating additional users from the browse operators window). The first user would be your supervisor (as per normal), and can be a windows account login. When adding additional Secwin users that are windows authenticated, the login must match the windows account name.

    Secwin is relying on Windows Authentication to do the login validation, so the login validation (strength of password, if there is one) is completely in the Windows account setup. If your client wants Windows Authenticated login, then it is up to them to ensure that their users have strong passwords for their windows login (and to have passwords at all).

    3.22. Question: What protocol does windows authentication use?

    Answer: It basically uses the windows GetUserNameEx name to fetch the currently logged in user, and then allows the user in based on a successful windows login (and whether that user has been added to secwin or not). This is not LDAP (i.e. controlled from a central server - which will use PAP or CHAP1/2 to interact with the LDAP server), but windows "user authentication" - IOW using a pre-authenticated user account to login to the application (no server interaction).

    This security is very weak if users can create their own user accounts on their PCs - since it means that they can create a user account of the same name to someone who has a login to the program (Secwin), they can essentially hijack the valid user's login.


    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>' & |

    4.2. Question: When I try to drag and drop a licence file into my application in Windows 7 it does not do anything.

    Answer:
    This is a manifest issue. Your application is running without the correct manifest settings, and so it is required to run elevated. Windows 7 seems to not allow dragging from a non-elevated application (like Explorer) to an elevated application. This can be temporarily repaired by unchecking the "include Default XP Manifest" option on the App Settings of the Global Properties of your application.

    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 mimic 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 dssw5.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 dssw5 file. See the Secwin Global Extension, Files tab.

    Under XP it's ok to place the dssw5 file in the windows directory. In Vista this isn't going to work. Recommended practice is setting the dssw5 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.

    Secwin - Initialize template generated code

    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.  The best is to perform the import in the Program Setup – “Secwin – After SetOwner and SetPath” in your data dll (ABC multi-dll apps) or EXE (single exe or legacy apps). Create a test to see whether the import has occurred or not.

    Typically you'd call this in your callback function (when the Secwin tables don't exist). The export file name is typically SecwinSecurityFile.bin It gets created in your working directory. You have the option to change the path. When testing, be sure to delete this file before exporting a second time.

    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.
    1. Remove the Create Secwin Menu template from your frame procedure (if you added it).
    2. Remove the User Login Here (from the frame)
    3. Remove the User Screen Security templates from each of the procedures where they've been added - or the Auto-populate UserScreen Security global extension template.
    4. in the global extension template, on the Options tab, delete all the procedure references in the Function Overrides group. Note: For Mutli-DLL applications, after doing this, uncheck the Functions are in another application and make sure the droplists are cleared as well).
    5. Remove the Secwin procedures from the application (that were added when you ran the Secwin template utility). If you now end up with a ToDo procedure, you'll need to export to TXA, delete the procedure and re-import.
    6. Remove any other Secwin templates you may have in your application.
    7. Remove the Secwin global extension template.

    6.7. Question: My app takes a long time to load after the login screen

    Suggestions:
    1. Make sure on the Global Properties, File control tab, 'DEFER OPENING FILES UNTIL ACCESSED' is checked

    6.9. Question: I get a lot of flickering on my controls that are Secwin controlled. How do eliminate this?

    Answer:
    Go to the User Screen Security template on that window, and check the Don't refresh access settings on GainFocus checkbox on that template prompt. You have something posting a refresh event to the window (possibly IMM checked) which is causing a GainFocus event. You must be aware that if this is a browse and you have record based access control, and another station changes the state (which would cause a user not to have access to specific features based on the record) - that this will not be refreshed.

    7.1. Question:
    Why should I upgrade from Secwin 3/4 to Secwin 6?

    Answer:
    Besides Secwin 3/4 being "sooo last century" you'll miss out on all the incredibly cool new features: What's new in Secwin 6? . We will continue building Secwin 4 for later new releases of Clarion, but the door is officially closed on fixes/tweaks/changes to older versions of Secwin. We have discontinued Secwin 3. (Old Secwin 3 builds are available from our archive https://www.capesoft.com/accessories/DownloadPatchesArchive.htm )

    7.2. Question: What must I change in my app when I upgrade from Secwin 3/4 to Secwin 4/6?

    Answer:
    1. Secwin 6 uses different table structures to previous versions of Secwin. When your program upgrades, the secwin data tables will be automatically upgraded to the Secwin 6 format, and the data file will be called dssw5.tps (not dssw2.tps or dssw4.tps). You can then use both Secwin3 and Secwin4 and Secwin 6 applications with the new data structure. This will occur seamlessly and without any action from your part. You need to be aware that any backup routines should now include the dssw5.tps file and not the dssw2/4.tps file.
    2. If you want to add Secwin Access Control support for your NetTalk Webserver application, take a look at the JumpStart
    3. For Secwin3 users: If you are using the Access Control side of Secwin, then you need to import the necessary access control windows into your application. Run the Create AccessControl windows template utility from the Application | Template Utility menu item in the Clarion IDE. You must also set the procedure names in the Secwin Global Extension template correctly.
    4. For Secwin3 users: You need to create a new register application to manage your registrations. Your previous application will not provide correct activation codes for your applications.
    5. For Secwin3 users: You must create a new SecwinRegisterProduct screen within your application - even if you have already created a MyRegisterProduct window in Secwin 3. Checkout the Creating a Register Product window section of the docs for more details.
    6. For Secwin3 users: If you are decrementing a counter, then you need to label your counter (which by default will be labeled 'Default Counter'). If you're doing table limits for your counter, then you'll want to change the limit to using the new table restrictions functionality.
    7. For Secwin3 users: Where you have used the ds_CurrentUserGroup function - you will need to recode this to using the replacement function: ds_UsersUserGroups. Because a user can now belong to multiple UserGroups, the old function cannot be made backward compatible to return a single UserGroup for a user.
    8. For IPD Driver users: you need to register the SLAIPD6S.DLL in your IP Server. If you are not using Secwin 4 applications in your Clarion DataServer, then you can de-register your SLAIPDS.DLL (the Secwin 4 DLL). You will also need to run a Secwin enabled TPS application on the TPS data at your IPServer in order to convert existing Secwin 3/4 data to the new dssw5.tps file. Note: If you run your Secwin 6 IPD server application and there are no users, it almost certainly means that you failed to complete this step before upgrading. In this case, delete your dssw5 file, and re-run the Secwin tps application to convert the dssw4 file. Make sure that your dssw5.tps file is created in the clariondataserver directory and that the size of the file is in proportion to the previous dssw4 file.
    9. Make the most of the additional function found in Secwin 6: What's new in Secwin 6?
    10. You will need to make some changes to your Register application if you are not using the register application that ships with Secwin or Secwin Online Server to issue activation codes (take note of the registerABC application in the Secwin examples):
    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/4 to Secwin 6?

    Answer:
    1. Purchase an upgrade to Secwin 6 from www.clarionshop.com. FAQ 7.5: Why is CapeSoft charging for an upgrade?
    2. You will then receive the new unlock saf code for the Secwin 6 downloads.
    3. Download the full install for Secwin 6 (from https://www.capesoft.com/accessories/downloads.htm)
    4. If you are not using the latest Clarion6 install, you need to download the patch for the version you are using (as well as the main install) from: www.capesoft.com\accessories\downloadpatches.htm
    5. Implment some of the features of Secwin 6 (see What's new in Secwin 6?)

    7.4. Question: How do I cater for existing clients using the old application when issuing activation codes?

    Answer:
    You can still issue old Secwin 3 activation codes with the new registration application. This means that you are not forced to upgrade everyone to the new Secwin 4 or 6 activation code system. They can each move over to the new application gradually if that is the method you prefer. Secwin 6 uses the same licence activation code format as in Secwin 4.

    For Secwin3 users:
    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/4 to Secwin 6?

    Answer:

    As much as we can we try to keep upgrades free. Charging an upgrade gives us the resources to pack in a whole lot of extra functionality into a product, that we would otherwise not be able to do. We are not forcing you to upgrade - and we will continue supporting and building Secwin 4 in future versions of Clarion. If you would rather not pay for the additional functionality offered in Secwin 6, you're welcome to continue using Secwin 4.


    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 6.00 CapeSoft introduced a paid-for upgrade, which means that the unlock code changed. You can continue using Secwin 4 and downloading the necessary install files with your existing Secwin 4 saf code, or you can upgrade to Secwin 6 (and make the most of all the functionality offered in the Secwin 6 package). To find out more about:
    7.7.Question: After upgrading from Secwin 3 to Secwin 4 (or 6), none of my users can log in.

    Answer:
    A Couple of things to try:
    1. You need to upgrade to the latest version of Secwin 6, delete the converted dssw5.tps file (make sure that you've still got your old dssw2/4.tps file hanging around) - and rerun your application. The new dssw5.tps file will be recreated correctly, and your users will be able to logon, etc.
    2. If you were using a Secwin 3 created window (i.e. not the DLL windows) - then you need to re-create the SecwinLoginWindow, using the template utility: Run the Create AccessControl windows template utility from the Application | Template Utility menu item in the Clarion IDE. You must also set the procedure names in the Secwin Global Extension template correctly. You should complete all the steps in FAQ 7.3 for a successful upgrade to Secwin 6.
    3. Make sure that you followed all the steps in FAQ 7.2.

    7.8. Question: Can I upgrade from Secwin 3 to Secwin 6?

    Answer:
    Yes. Incidentally Secwin 3 is deprecated, although you can still download the last build from our archives: https://www.capesoft.com/accessories/DownloadPatchesArchive.htm

    7.9. Question: What happened to Secwin 5?

    Answer:
    As you probably know we number each build that we release. Secwin 4 is now up to build 4.99 (at the time of writing). If we released the new Secwin as Secwin 5 then we'd have a problem updating future versions of Secwin 4, should any be necessary. Rather than create a problem, when none currently exists, we took the simplest solution and are starting this version of Secwin at 6.00.

    Click here for Secwin Runtime Error messages

    Secwin Compiler Error Messages and Asserts

    Incorrect Prototype for own Login Procedure

    You need to change your Login Procedure as laid out in the Create your own Login Window section of this doc.

    3rd party Compile Error screenshot

    You have a 3rdParty template that is incorrectly generating code into one of the imported Secwin windows. Try disabling all added 3rdParty templates (on those particular windows) until the compile error disappears.

    You must at least include one file of AccessPoints for the control template to ....

    The message is descriptive in it's solution (scrolling left will show the full content of the message - as well as reading the combined asserts). Essentially you have created (imported) a Global SetAccess window without completing all the steps required to complete this addition. Work through all the steps in the Creating your own GlobalSetAccess window section of the docs in order to resolve this assert.

    Error(2): cif$fileopen <filename>.sac The system cannot find the file specified.

    In your SecwinSetAllAccess window, in the Extension templates, you will find a Secwin's set access globally control template. On that template, is a list of files to include to generate the access points list tree for the SecwinSetAllAccess window (it's called "Files containing Access points"). One of these files in the list is not being generated at compile time. You need to delete this file from the list, so that the compiler does not try and link an obsolete file when compiling.

    If you are using this in a Multi-DLL application, then one of two things is happening:
    1. You haven't compiled the dlls yet (that still need to create the sac file).
    2. You've included a sac file from a dll that is not set to generate a sac file (maybe doesn't have the Secwin template added, or has this option disabled on the global extension template)
    The sac file is only created (and maintained) at generate time, so if you have included your GlobalSetAccess window in your Data DLL, you need to compile it again - after compiling your other apps - to make sure it has the most recent version of all the sac files from the other apps.

    ds_UsersEx() - No matching prototype available.

    You have a queue that is prototyped incorrectly. The ds_UsersEx function is expecting a queue of the following structure:

    ds_UserQueueEx Queue,pre(_dsuqex),type
    Name string(40)
    Surname string(40)
    Login string(128)
    UserGroup Long
    Number LONG
    LastPasswordChangeDate LONG
    Reserved1 LONG
    Reserved2 STRING(12)
    Reserved3 STRING(20)
    end

    Probably the best would be to define your queue as follows:

    MyUserQ                queue(ds_UserQueueEx)
                                  end     

    Unknown Identifier: PROP:IPRequestCount and AppsKey.

    First search you drive for an old secequ15.clw file. Remove all copies that are not in your clarion6\3rdparty\libsrc directory and recompile.

    If you are still getting this error, then check the I'm using 9046 (include the secequ60.clw file) checkbox in the global extension template. (This should only be necessary for Clarion 6.2 users on patch 9046).

    Syntax error: Field not found: CounterDescription

    Change the variable used in your handcode to Description. If you get an 'Unknown' field in a list, you need to remove it and add the Description field.

    Unresolved External DOS in Secwin6.OBJ

    Typically you'd get this error in Clarion 7.3 and up where you're compiling your application in Local mode. You need to add the DOS driver to your project:


    Secwin Runtime Error Messages

    Access Denied

    The user attempted to log in, but he does not have access to this program, or program area. In other words he has a setting of 'No Access' on the Operator Browse screen for this program. See Operator Browse and Form.

    Error reading License File : __________________

    An unexpected disk error was encountered reading the security file.

    Incorrect Activation Code. Please consult your application supplier.

    The activation code the user typed in was not valid. This is typically caused by either

    1. The date on the PC is more than 7 days after the date when the activation code was issued.
    2. The user didn't set all the settings the same as they were set when the activation code was generated
    3. When generating the activation code the developer used the wrong License Name and Seed Code. The correct values can be found on the Global Extension, Licensing tab.

    Incorrect Old Password

    The user attempted to change the password, but they entered the wrong password when asked to enter their old password.

    Invalid Login

    The user was logging in, but entered an invalid login code.

    Invalid Password

    The user was logging in, and entered an incorrect password.

    Invalid Security file : PIN missing.

    The security file does not have the necessary PIN number stamped into it. See PIN Numbers.

    New password cannot be the same as old password

    When entering a new password, the new password cannot be the same as the old password.

    New passwords must match. Please try again.

    The user was attempting to change their password. They were asked to enter the new password twice. However the two copies of the new password do not match.

    No users exist for this Application / Security Area. Do you want to add a new user ?

    This is the first time you have run the program, and there are no users in the security file. Click on Yes to create the first user.

    No users exist for this Application / Security Area. Do you want to grant access to an existing user ?

    This is the first time the program has been run on this machine. There are users in the security file, but none of the users has access to this application. Select Yes to allocate access to one of the existing users.

    Password cannot be blank

    When entering a new password, then a blank password is not allowed.

    Password cannot be the same

    When entering a new password, the new password cannot be the same as the old password.

    Password must contain 6 Alpha and 3 Numeric characters

    If the Force Long Password on the Login template is on, then the user, when they change their password, must have a password containing at least 6 alpha and 3 numeric characters.

    The Security tables are non-existent. Please contact your Application Supplier to obtain these files.

    Possible causes and their fixes:
    1. You have most likely turned off the ability to create security files (which often is the correct option) and your application can't find the dssw5.tps file. You need to ensure that the application is looking for the dssw5.tps file in the correct place.
    2. The dssw5 is on a different PC and PC where the application is running does not have sufficient read/write access to the networked PC where the data resides.
    Run your application with the command-line switch /SecDbg, and immediately after the message you'll get a stop with the actual disk error.

    There seems to be an error with your PC date. The last time the program was run was _________

    This error occurs if the Expiry date in the license is less than 1/1/2095 and the date on the PC goes backwards. On a network this can imply that another PC has a date set in the future.

    There was an error accessing a License File. The file was ________ and the error was _______.

    An unexpected error was encountered trying to enforce the Network Copies feature. Typically this is caused by some kind of disk error.

    This feature is not available in your Level of the program. Consult your application supplier for more information.

    The user does not have a sufficient LEVEL to run this procedure.

    This is a super user created by the developer and cannot be deleted.

    The developer has set a Super User setting on the Login extension template identifying this user. You cannot delete the user, but you can set the access rights to No Access.

    Too many people are already running the system. People already logged in include _________.

    The user has exceeded the number of concurrent network copies you have allowed.

    Unable to open Security Access file. Consult your application supplier.

    The Security file is missing. See Creating the Security file, and Locating the Security File.

    Unable to write modified access : __________

    An unexpected disk error was encountered writing to the security file.

    Unable to reload licence

    You are calling ds_RegisterProductEx when there is no valid pre-existing licence. Check the ds_RegisterProductEx function for more details.

    Your access to this part of the program has been restricted

    The user is attempting to access a screen to which he doesn't have access. This access has been set by a Supervisor using the Set Access (Ctrl F8) screen. This error also appears when an Operator tries to access a Security maintenance window, like the Operator Browse..

    You are not licensed to use this module.

    The user has tried to access a procedure that belongs to an optional module, where that optional module is not activated.

    Your product has expired. Consult your application supplier.

    The date on the PC is greater than the expiry date set when the license was issued.

    Your Security file has become corrupted. Consult your application supplier for a new activation code.

    Possibility 1: The date on the security file has gone backwards. This may be because the user has restored a backup, or because the user is attempting to use an old security file to gain access to the program (i.e. the date of the Security file has gone backwards). This check can be disabled by checking the "Disable Registry Check" in your Secwin global extension template . Despite the dramatic warning the file is not corrupted. To restore the program issue a new activation code.

    If you have 2 applications using the same security file (or multiple instances of the dssw5.tps file on the same machine - even if they are used by different applications), you will need to check the Disable Licence File registry check option in both applications.

    Possibility 2: In Secwin 4 (and indeed for SQL versions of Secwin 3) - the tables are now not encrypted (except for the fields that are essential to Access and Security). This means that the tables are open to use for reading from your applications. It also means that tables can be manipulated from external sources. In order to protect your access control - if the files are tampered with, Secwin will detect this and disallow the running of your application. In order to allow the user to continue using the application, they can either:

    1. Restore the dssw5.tps (or equivalent SQL tables) from backup. This is a much better option, as it will restore the tables to a state prior to tampering.
    2. 2.1. If the corruption error occurs in the access files your users/clients can request a Security Code from you (preferably using email) - that you will be able to generate with the SecwinFileFixer utility in order for Secwin to repair the AccessControl tables. Your users/clients will have to enter this code in the error Window that is displayed when this error is detected. Please see SecwinFileFixer for an example of this screen.
      2.2 You can disable the security files CRC check in the Global Extension template (in the Data-dll template if this is a Multi-DLL application). This essentially weakens the AccessControl of your application - as it means that the security files can be tampered with, without your application being aware of it. Only the Secwin DLL should be permitted to write to the Security files.
    3. 3.1 If the corruption error occurs in the license file you will have to delete the license file and your users/clients will need to obtain a new Activation Code in order for the application to be reactivated. Your users/clients will have to enter this code in the Registration Window in your application.
      3.2 Disabling the CRC Check wil have no effect on the license table. If a CRC error is detected in the licence table, the licence will be reset, and a new activation code will be required to be issued in order for the user to re-activated the licence.
    You can disable the security files CRC check in the Global Extension template (in the Data-dll template if this is a Multi-DLL application). This essentially weakens the AccessControl of your application - as it means that the security files can be tampered with, without your application being aware of it. Only the Secwin DLL should be permitted to write to the Security files.

    Note: Disabling the CRC Check will only disable the CRC check on the AccessControl tables. If this occurs in the licence table, the licence will be reset, and a new activation code will be required to be issued in order for the user to re-activated the licence.

    The security licence is used before it is loaded (i.e. ds_LicenceOk is called before ds_UseLicence)

    Basically you have a procedure that is trying to use the licence before the licence is loaded. The Load licence method is called ds_UseLicence, and thereafter ds_LicenceOK will use the licence that is loaded by ds_UseLicence. Either you're calling a procedure before the procedure where your Secwin Login Here template is added - or your procedure where the Secwin Login Here template is not being called. If you have added the global template 'Autopopulate User Screen Security', then you may have a window called before the licence is loaded that is using the User Screen Security template. In that window (could be a window like the RuntimeFileManager window) you need to disable the auto-populated User Screen Security template.

    Error 2: Names (or Operators,etc)


    There was an errorcode 2 in attempting to open one of the security files - i.e. file does not exist when trying to open the names file. This probably means one of the following:

    1. that the exe is looking for the dssw5.tps file in the incorrect place (i.e. it's installed in the incorrect place).

    2. that the exe is not setup to create the dssw5.tps file.

    3. that the user running the machine does not have sufficient access rights for the program to create the dssw5.tps file (even although the exe is setup to create the security file).

    Technical Support

    CapeSoft Support
    Email
    Telephone +87 828 0123

    Version History

    Download latest version here

    What's new in Secwin 6?

    Getting compile errors after upgrading? Check the Compile Errors Section.

    NOTE: When you upgrade NetTalk to version 6.38 (for NTWS controlled access control), in your Secwin_ScreenAccess table, you must change your SessionID from a long to a string(30) (see FAQ 0.10 for details).
    NOTE: When you upgrade from NetTalk 6 to NetTalk 7, you must reset the "Delete Session on logout" switch in the WebServer procedure's NetTalk or NetSimple Object extension prompts:



    Version 6.54 (30 November 2023) GOLD Version 6.53 (8 May 2023) GOLD Version 6.52 (25 October 2021) GOLD Version 6.51 (24 May 2021) GOLD Version 6.50 (6 September 2020) GOLD Version 6.49 (31 May 2019) GOLD Version 6.47 (17 September 2018) GOLD Version 6.45 (12 June 2018) GOLD Version 6.44 (31 January 2018) GOLD Version 6.43 (30 January 2018) GOLD Version 6.42 (5 December 2017) GOLD Version 6.41 (21 April 2017) GOLD Version 6.40 (8 February 2017) GOLD Version 6.39 (9 January 2017) GOLD Version 6.38 (4 July 2016) GOLD Version 6.37 (12 December 2015) GOLD Version 6.36 (3 March 2015) GOLD Version 6.35 (2 March 2015) GOLD Version 6.34 (31 July 2014) GOLD Version 6.33 (1 July 2014) GOLD Version 6.32 (2 June 2014) GOLD Version 6.31 (11 February 2014) GOLD Version 6.30 (20 January 2014) GOLD Version 6.29 (2 January 2014) GOLD Version 6.28 (17 December 2013) GOLD Version 6.27 (13 November 2013) GOLD Version 6.26 (15 October 2013) GOLD Version 6.25 (29 August 2013) GOLD Version 6.24 (28 August 2013) GOLD Version 6.23 (5 August 2013) GOLD
    Version 6.22
    (25 April 2013) GOLD Version 6.21 (16 April 2013) GOLD Version 6.20 (12 March 2013) GOLD

    Version 6.16 (8 January 2013)

    Version 6.15 (21 November 2012)

    Version 6.14 (27 August 2012) Version 6.13 (16 August 2012) Version 6.12 (1 August 2012) Version 6.11 (4 May 2012) Version 6.10 (1 May 2012) Version 6.09 (5 March 2012) Version 6.08 (22 February 2012) Version 6.07 (20 February 2012) Version 6.06 (17 February 2012) Version 6.05 (2 February 2012) Version 6.04 (17 January 2012) Version 6.03 (21 October 2011) Version 6.02 (22 September 2011) Version 6.01 (15 September 2011) Version 6.00 (9 September 2011) Version 4.99 (20 July 2011) (No TXA import required if upgrading from 4.58 or up) Version 4.98 (15 April 2011) (No TXA import required if upgrading from 4.58 or up) Version 4.97 (23 February 2011) (No TXA import required if upgrading from 4.58 or up) Version 4.96 (9 February 2011) (No TXA import required if upgrading from 4.58 or up) Version 4.95 (10 January 2011) (No TXA import required if upgrading from 4.58 or up) Version 4.94 (7 December 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.93 (19 November 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.92 (22 October 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.91 (6 September 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.90 (23 August 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.89 (14 July 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.88 (4 June 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.87 (20 April 2010) (No TXA import required if upgrading from 4.58 or up)
    Summary: Fix GPF in ds_SaveLicenceToXMLEx, Fix IPDriver Access assigning Version 4.86 (14 April 2010) (No TXA import required if upgrading from 4.58 or up)

    Summary: See below. Also see Translating Secwin Windows on changed translation requirements for Secwin4. Version 4.85 (8 February 2010) (No TXA import required if upgrading from 4.58 or up) Summary: Clarion 7.1 duplicate compile error fix, fix for long passwords required, fix for corrupt licence (may require an initial re-activation). Version 4.84 (25 January 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.83 (22 January 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.82 (19 January 2010) (No TXA import required if upgrading from 4.58 or up) Version 4.81 (13 January 2010) (No TXA import required if upgrading from 4.58 or up)

    Fix regression in 4.80 - was not displaying the UserGroups in SQL versions. Version 4.80 (31 December 2009) (No TXA import required if upgrading from 4.58 or up)

    Clarion 7.1 compatible build Version 4.79 (8 December 2009) (No TXA import required if upgrading from 4.58 or up)

    Some optimization - especially for Oracle. Version 4.78 (24 November 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.77 (9 October 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.76 (3 September 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.75 (23 July 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.74 (10 July 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.73 (3 July 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.72 (1 July 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.71 (18 June 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.70 (5 May 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.68 (16 April 2009) (No TXA import required if upgrading from 4.58 or up) Version 4.67 (25 February 2009) (No TXA import required if upgrading from 4.58 or up)

    Summary: A couple of minor tweaks. Affects programmers using AppPin, Super Users, and/or UserGroups. Version 4.67 (25 February 2009) (No TXA import required if upgrading from 4.58 or up)
    Summary: A couple of minor tweaks. Affects programmers using AppPin, Super Users, and/or UserGroups. Version 4.66 (22 January 2009) (No TXA import required if upgrading from 4.58 or up)

    Summary: Optimization for SQL (mostly - but also TPS), some template tweaks. A TXA import is recommended for speed improvement. Version 4.65 (24 December 2008) (No TXA import required if upgrading from 4.58 or up)

    Summary: Optimization for SQL (mostly - but also TPS), some template tweaks. A TXA import is recommended for speed improvement. Version 4.64 (26 November 2008) (No TXA import required if upgrading from 4.58 or up) Version 4.63 (21 November 2008) (No TXA import required if upgrading from 4.58 or up) Version 4.62 (4 November 2008) (No TXA import required if upgrading from 4.58 or up)

    Summary: Optimization for SQL - particularly for UserGroups, Encryption Code. Version 4.61 (23 October 2008) (Minor release)

    Summary: Template change for Clarion7 support.

    Version 4.60 (17 October 2008) (Minor release)

    Summary: Release 4.59 did not include all the dlls for all the backends.

    Version 4.59 (15 October 2008) (Minor release)

    Summary: Fix for UserNumbers > 32767 Version 4.58 (16 September 2008) (TXA import recommended)

    Summary: Some startup optimization for SQL, IPDriver support for separate datapath, better UserGroup support (editing) in the TXAs. Version 4.57 (3 September 2008) (No TXA import required if upgrading from a version greater than 4.55) Version 4.56 (22 August 2008) (AccessControl windows TXA import recommended) Version 4.55 (13 August 2008) (No TXA import required if upgrading from a version greater than 4.54) Version 4.54 (5 August 2008) (AccessControl windows TXA import recommended) Version 4.53 (29 July 2008) (No TXA import required if upgrading from a version greater than 4.43) Version 4.52 (11 July 2008) (No TXA import required if upgrading from a version greater than 4.43) Version 4.51 (10 July 2008) (No TXA import required if upgrading from a version greater than 4.43)

    Summary: Firebird support, support for a large number of Access Control groups on one window (where the access control group string compiles to > 1024) Version 4.50 (27 June 2008) (No TXA import required if upgrading from a version greater than 4.43) Version 4.49 (11 June 2008) (No TXA import required if upgrading from a version greater than 4.43) Version 4.48 (5 June 2008) (No TXA import required if upgrading from a version greater than 4.43) Version 4.47 (6 May 2008) (No TXA import required if upgrading from a version greater than 4.43) Version 4.46 (21 April 2008) (No TXA import required if upgrading from a version greater than 4.43) Version 4.45 (9 April 2008) (No TXA import required if upgrading from a version greater than 4.43) Version 4.44 (21 February 2008) (Recommend Access Control windows TXA import to optimize the BrowseUsers) Version 4.43 (6 February 2008) Version 4.42 (30 January 2008) Version 4.41 (25 January 2008) Version 4.40 (24 January 2008) Version 4.39 (22 January 2008) Version 4.38 (11 December 2007) Version 4.37 (5 December 2007) Version 4.36 (3 December 2007) Version 4.35 (29 November 2007) Version 4.34 (26 November 2007) Version 4.33 (22 November 2007) Version 4.31 (15 November 2007) Version 4.30 (14 November 2007) Version 4.29 (6 November 2007) Version 4.28 (5 November 2007) Version 4.27 (26 October 2007) Version 4.26 (24 October 2007) Version 4.25 (23 October 2007) Version 4.24 (18 October 2007) Version 4.23 (17 October 2007) Version 4.22 (12 October 2007) Version 4.21 (9 October 2007) Version 4.20 (1 October 2007) Version 4.19 (21 September 2007) Version 4.18 (20 September 2007)

    Note
    : Although support for the IPDriver is fixed, upgrading from the Secwin 3 tables is still not possible yet. Version 4.17 (18 September 2007)

    Note:
    Although support for the IPDriver is fixed, upgrading from the Secwin 3 tables is still not possible yet. Version 4.16 (14 September 2007) Note: If you are not using SOS to issue registration codes (you are using the register application) - then you will need to recompile your application from the example shipped with Secwin. If you do not do this, then your registration codes will fail if you are not currently including the Dealer string in your registration codes. Version 4.15 (29 August 2007) Version 4.14 (23 August 2007) Version 4.13 (16 August 2007) Version 4.12 (10 August 2007) Version 4.11 (8 August 2007)

    Note
    : If you have an existing Login Window, then you will need to change it (documented in the Creating Your Own Login Window section) Version 4.10 ( July 2007) Version 4.09 (26 July 2007) Version 4.08 (26 July 2007) Version 4.07 (25 July 2007)

    Note:
    If you are using your own windows (for AccessControl) - then you need to re-import the windows using the template utility (because the OwnLogin method has changed). Version 4.06 (23 July 2007)

    Note: Because of a required file structure change to the Licence security file, your licences issued after the release of Secwin 4 will not work, your customers will need to re-activate their licences. Version 4.05 (19 July 2007) Version 4.04 (18 July 2007) Version 4.03 (17 July 2007) Version 4.02 (16 July 2007) Version 4.01 (12 July 2007) Version 4.00 (12 July 2007) Version 3.99e (10 July 2007) Version 3.99e (10 July 2007) Version 3.99d (6 July 2007) Version 3.99c (3 July 2007) Version 3.99b (29 June 2007) Version 3.99a (28 June 2007) Version 3.99 (26 June 2007)

    New Features: Fixes: Version 3.47 (19 June 2007) Version 3.46 (6 June 2007) Version 3.45 (11 May 2007)

    * Include latest Makeover classes into Secwin.

    Version 3.44 (18 April 2007)

    * Include latest Makeover classes into Secwin.

    Version 3.43 (14 March 2006)

    * Include latest Makeover classes into Secwin.

    Version 3.42 (13 December 2006) Version 3.41 (29 August 2006) Version 3.40 (27 July 2006) Version 3.39 (29 June 2006) Version 3.38 (15 June 2006) Version 3.37 (10 May 2006) Version 3.36 (27 April 2006) Version 3.35 (27 April 2006) Version 3.34 (21 April 2006) Version 3.33 (21 April 2006) Version 3.32 (18 April 2006) Version 3.31 (24 Feb 2006) Version 3.30 (1June 2005) Version 3.28 (22 December 2004) Version 3.27 (26 October 2004) Version 3.26 (22 January 2004) Version 3.25 (12 January 2004) Version 3.22 (14 July 2003) Version 3.21 Version 3.20 Version 3.19 Version 3.16d beta 6 Version 3.16c beta 5 Version 3.16 beta 4 Version 3.15 beta 3 Version 3.1 beta 1 Version 3.11 beta 2 Version 3.0 Beta 5 :

    SPECIAL NOTE : If you used Beta 3, or Beta 4, with any of the SQL driver packs (MsSql, SQLAnywhere, Oracle, ODBC etc) then you will most likely need to Drop all the DSSWn Tables and let Secwin re-create them. This is due to some changes which were required by SQL in order for Secwin to work properly. Version 3.0 Beta 4 :