You may wish to sell certain reports to customers. The problem is that once one customer has imported such a report, they can easily give it to other customers, preventing you from receiving revenue from those additional customers.

Stonefield Query supports report licensing. Only customers with specific serial numbers for their Stonefield Query licenses can import a licensed report; others will get a "You are not licensed to use this report" error when they try to import it.

The list of valid serial numbers is stored in plain text in the SFX report file; however, to prevent someone from editing the serial numbers in the file, a checksum is included. If someone changes any of the serial numbers, the checksum won't match and they'll get a "The license for this report is invalid" error.

Here's how to license a report:

  • Create the report.

  • Export it to an SFX file.

  • Choose the Generate Checksum function from the Stonefield Query Studio File menu, enter a comma-delimited list of the valid serial numbers, and click OK. Stonefield Query Studio creates the text of the sdata element described below and places it on the Windows Clipboard.

  • Edit the SFX file using a text editor like Notepad.

  • The SFX file contains XML. One of the last elements in this XML is . Edit this so it appears as follows:

      <sdata>serial number 1,serial number 2,...,serial number N,checksum</sdata>

serial number 1 is the first serial number authorized to use this report, serial number 2 is the second, and so forth. checksum is the checksum. The easiest way to edit this element is to select "<sdata/>" and paste the contents of the clipboard to replace it (assuming you used the Generate Checksum function earlier and didn't place anything else on the Clipboard).

You could also automate the generation of the licensing information; for example, if you sell your reports in a Web store, you would obtain the Stonefield Query serial numbers of the customer, calculate the CRC32 checksum on the list of serial numbers, and then update the SFX file prior to sending it to the customer. Visual FoxPro developers can use code such as the following (assuming lcSerialNumbers is a string containing the comma-delimited list of serial numbers, lcReportFile is the name and path for the original SFX file, and lcCustomerFile is the name and path for the SFX file to send to the customer):

* Calculate the checksum.

lcChecksum = sys(2007, lcSerialNumbers, 1)

* Concatenate the serial numbers and the checksum.

lcSData = lcSerialNumbers + ',' + lcChecksum

* Read the original SFX file into a variable.

lcReport = filetostr(lcReportFile)

* Replace the empty <sdata/> element with a new <sdata> element.

lcReport = strtran(lcReport, '<sdata/>', '<sdata>' + lcSData + '</sdata>')

* Write the XML back to a file specific for this customer

strtofile(lcReport, lcCustomerFile)

Developers using other languages can do something similar using the appropriate functions for their language.