Technology Working Group
Working Technology Specification
Primary Health
PHForms Server-Module Programming Interface
Protocol 5 revision 1 – Forms
Server 5.145/HTTP1.1
Copyright ©2004 Primary Health Ltd
All trademarks &
registered trademarks mentioned are for illustration purposes only, and remain
the property of their respective owners. ALL OTHER RIGHTS RESERVED.
This document is indexed with status 410. The
information contained herein is PRIVALEDGED INFORMATION and is strictly
internal. Please ensure that you follow the document confidentiality rules when
viewing or printing this document.
Status 410 documents MUST be protected – Leaking this information may result in
termination of employment.
Contents
The PHForms Modular Architecture
Module File Storage & Deployment
PHForms MPI Structure Reference
Generic
Function Call Result Type
Module
Version Information Structure
Resource
Enumeration Results Structure
PHForms MPI Function Reference
PHForms MPI Constants and Macros
Further Information & Suggested Reading
This Working Technology Specification (WTS) is concerned solely with the software interface and API layer between the Primary Health Forms Server and individual form modules. This document is intended primarily as an API reference for developer’s wishing to create new PHForms.5 modules, especially as the information it contains is in a fairly ‘low-level’ format. While certain topics addressed here may be of interest in a general ‘how does it do that’ informational way, we do assume some knowledge of programming in C, HTML, Java[script], and the specifics of accessing and using APIs provided as a set of Dynamic Link Libraries (DLLs). If you are looking for a more general discussion of the PHForms architecture, including an overview of how modules interact with the system, see the PHForms Technical Outline (doc# 041-55122904-0420-021)
The term “Primary Health” is used throughout this document, to refer to both Primary Health Limited and the Primary Health Solution. Usually context will make it obvious which Primary Health is being referred to. Where this is not the case, however, we will specify. Since this is a technical document, we assume some technical knowledge on the part of the reader. You should be at least aware of the following terms, and the technologies that lie behind them: Software, Application, Microsoft® Windows®, Executable, Dynamic Link Library (DLL), Client, Server, Hypertext Transfer Protocol (HTTP), Hypertext Markup Language (HTML) and Extensible Markup Language (XML).
In the context of this document, the word Forms refers to on-screen versions of paper-based forms. We do use the word as it is used in a GUI Development context, to refer to windows on screen.
A similar situation arises with the word Resources. The Win32® SDK refers to resources as ‘binary data that a resource compiler or developer adds to an application's executable file … [that] contains any data required by a specific application’. In the context of a PHForms Module, a resource is a discreet element contained within a module, such as an image, the XML code for a form, and so on. While the meanings are similar the implementation of the two methods is completely different.
All code in this document is shown in the courier new typeface.
Code is always shown in C, using Borland syntax. Things like calling conventions, references, dereferencing and so on may differ slightly with different compilers.
When referencing integer types, we use char to mean 8-bit, short to mean 16-bit, and long to mean 32-bit. Signed and unsigned work as you’d expect.
Where structures include pointers (to null-terminated strings, for example) any calculation of the size of that structure should include the pointers only, not the string itself. Pointers are always 32-bit values.
The Primary Health Forms (PHForms) Engine is designed around a modified distributed two-tier (or client/server) design architecture, with the Forms Server kept separate from the Renderer on the client side. Drilling down into the system, the Server itself is also implemented as a number of ‘layers’, all of which fall into two categories – Server and Module. The Server provides the general-purpose transport and storage for the forms without being concerned with the actual layout and code contained in those forms. This layout and code information is abstracted to the Module layer, giving a further level of architectural separation and thus maintaining flexibility and scalability.
In order that the Server can communicate with whichever modules are installed on a particular system, PHForms provides a standard interface for communication between the two layers. This interface (also known as the PHForms Module Programming Interface, or MPI) defines not only the on-disk format of a module, but also a number of standard functions, types and protocols that must be implemented by that module. In order to function with PHForms a module must adhere to these standards.
The actual design of the server and it’s modules are beyond the scope of this document – we are concerned here only with the interface provided by PHForms between the two layers, as described in the previous paragraph.
At the most basic level (i.e. that of a file on a disk) PHForms modules are compiled binary images that contain at least a standard set of functions as defined by this interface specification.
More specifically, these compiled binary files conform to the Microsoft® Windows® Dynamic Link Library (DLL) format. DLL files are compiled code libraries that can be linked by Windows applications. See the Windows Platform SDK (http://msdn.microsoft.com/platformsdks/) or your compiler’s documentation for more information on the format and structure of DLLs, and how they are compiled.
PHForms Modules always have filenames ending in ‘.phform’ instead of ‘.dll’.
To claim to be a PHForms module, a Windows DLL must conform to the following rules:
It should be noted that a PHForms module does not necessarily equal one PHForm.
A single module may contain a number of forms, or equally it may contain none.
Modules must implement (and export) a number of standard functions as listed below. As well as this code, modules may also contain a number of ‘resources’, which contain data stored in an arbitrary format. From the point of view of the client rendering engine, each resource corresponds to a different request URI. Resources can contain, for example, XML form source, image data, callable functions, and much more.
Resources are retrieved by the PHForms Server through the resource functions. Modules can implement actual storage of resources however they choose and provide a standard interface through these three functions.
The PHForms Server calls the PHGetModuleInfoBlock function exported by a module whenever it needs general information about that module. The Module Information Block is a structure that contains general information about the module, such as it’s display name, copyright information, the functions it exports and so on.
The format of the Module Information Block is described in detail later in this document.
All Modules must export at least the following functions:
PHRESULT __stdcall PHGetModuleInfoBlock (PHMIB
*mib);
PHRESULT __stdcall PHEnumResources (PHENUMRES
*result);
PHRESULT __stdcall PHResourceByName (PHRESINFO
*resinfo);
PHRESULT __stdcall PHResourceByNum (int index,
PHRESINFO *resinfo);
PHRESULT __stdcall PHGetResource
(PHRESINFO *resinfo, char
*buf, long buflen);
PHRESULT __stdcall PHCallResource (PHRESINFO
*resinfo);
As you’ll notice, all of these exports use the stdcall (equivalent to WINAPI) calling convention. How this is specified may differ according your compiler.
The MPI is fairly compact, and requires only one include directive. All the structures, types, macros etc are incorporated via the phfmpi5.h header.
When compiling modules your source code must include the following directive.
#include “pfhmpi5.h”
Ideally this should be placed near the top of the file.
This section describes all the structures and other typedefs used by the MPI. These are defined in the phfmpi.h header file as described above.
Most of the standard functions defined by the PHForms MPI use the PHRESULT type for their return value. This is an unsigned long typedef. The MPI defines a set of values for use with this, with names starting PH_RESULT_ followed by a specific name.
The PHVERSIONINFO structure holds version information for a module.
A pointer to a Version Information structure is returned in the Module Information Block.
typedef struct {
unsigned short wMaj;
unsigned short wMin;
unsigned short wRelease;
unsigned short wBuild;
char *szSpecifier;
char *szExtraInfo;
} PHVERSIONINFO;
wMaj This should
contain the major portion of the version number for the module when returned.
wMin This should contain
the minor portion of the version number for the module when returned.
wRelease This should
contain the release number of the module when returned.
wBuild This
should contain the build number of the module when returned.
szSpecifier (Optional)
This may contain a version specifier for the module
when returned. A specifier is a string that qualifies
the version number, such as ‘Alpha’, ‘Final’, ‘Private’, etc.
szExtraInfo (Optional)
Can contain any extra version-related information.
The Module Information Block is stored in the PHMIB structure. This contains information such as the module’s name, copyright information, and so on.
typedef struct {
unsigned char cbSize;
unsigned long dwSignature;
char *szName;
char *szCopyright;
PHVERSIONINFO
*lpVersion;
char *szAdditionalInfo;
} PHMIB;
cbSize This
will be set to the size of the structure in bytes when the PHGetModuleInfoBlock
function is called. Modules can use this to check that they’re receiving the
correct version of the structure. If the sizes differ, the module can either
fail or continue, treating the structure as it is shown. While new fields may
be added the original fields will never be changed.
dwSignature This
should be set to the standard PHForms Module Signature, 0x2bad2bad. This is
used for validation of the module and so must be set correctly by a module.
szName Set
this to the name of the module. The server uses this for display purposes.
szCopyright (Optional)
Can contain any copyright information the module would like displayed to the
user.
lpVersion Points
to a PHVERSIONINFO structure that contains version information for the module.
Modules can point this to a global variable within their address space, since
this space is mapped into the caller’s address space at runtime.
szAdditionalInfo (Optional) Can contain
any additional information as required.
The resource information block is used to hold information about a resource. Specifically, when a module implements the MPI ‘fetch resource’ functions the PHRESINFO structure is used to return the information.
Note: The PHRESINFO
structure does not store the actual data for the resource – This is obtained
using the GetResource function in conjunction with a
Resource Information Block, or the CallResource
function for handler type resources.
typedef struct {
unsigned char cbSize;
unsigned long dwType;
char *szResourceName;
char *szContentType;
char *szAdditionalInfo;
char RESERVED[255];
} PHRESINFO;
cbSize This
will be set to the size of the structure in bytes when it is passed to a
module. Modules can use this to check that they’re receiving the correct
version of the structure. If the sizes differ, the module can either fail or
continue, treating the structure as it is shown. While new fields may be added
the original fields will never be changed.
dwType This
indicates the general type of the module. The PH_MODULE_TYPE_XXXX values are
used for this.
szResourceName The
name of the resource, as used when searching.
szContentType The
content-type string that should be returned in the HTTP header for this
resource.
szAdditionalInfo Any
additional information as required.
RESERVED Reserved for future expansion.
PHForms Functions
The PHForms MPI represents a highly-specified, flexible, powerful programming interface for the development and deployment of modules for Primary Health.
Thanks to the standards and interfaces specified in the PHForms MPI, modules have almost unlimited scope for features and function.
By understanding the concepts described in this document and adhering to them when designing and creating your module, you ensure that your product will fit in to the Primary Health Forms Engine and work reliably and consistently.
More information about PHForms and the Primary Health Solution can be found at:
www.primaryhealth.co.uk/products.html.
For more details about XML, XHTML, or any of the other web technologies mentioned in this document, see the World Wide Web Consortium (W3C) website:
The following Primary Health Technology Documents are also relevant to PHForms:
PHForms MPI Developer Reference (Document 041-14122604-0420-021)
PHForms URI Specification (Document 041-15710603-0420-021)