system os2v2 dll initinstance terminstance # # object file(s) # file YourFile.obj # # the DLL name # name YourLib.dll library powerapi.lib # # the module name in upper case # option modname=YOURLIB # # The following are VERY IMPORTANT to ensure # your DLL does not conflict with the main # PowerWeb DLLs. # option manyautodata option caseexact segment type code loadoncall shared segment type data loadoncall nonshared readwrite # # the exported functions... case sensitive! # export YourFunctionCall
Suggested Location for C Modules:
Assuming your server root is "\powerweb",
put your library DLL in the directory "\powerweb\bin", so that you can
load it with the URL "/bin/module!function" where "module" is the
name of your DLL (without the file extension) and "function" is the
name of the function within your DLL to call.
Example URL: "/bin/property!ShowMenu"
PowerWeb automatically adds the "bin" sub-directory to your LIBPATH environment setting on PowerWeb startup.
PowerWeb automatically associates files within the bin directory as compiled DLL extensions. This is set up through the URL Alias Editor. If you create sub-directories under this directory, they will also be recognised as compiled DLL extension directories.
You can create further directories in other locations by simply defining an alias to that directory and giving it an object type of "API Script". Remember to include that directory on your LIBPATH.
Compile your program with IBM's VisualAge C++ version 3 (with at least fixpack CTC304 installed) with debugging on, then load powerweb through IPMD (also known as ICSDEBUG) as follows (assuming PowerWeb 4.01 release 3 is installed on the E drive):
e:Then put a "load occurrence" breakpoint on your DLL (mentioning the FULL path in the edit box).
cd \powerweb\sys401.r3\bin
ipmd pwchain -de:\powerweb
IPMD will stop PowerWeb when your DLL is loaded. You can then set breakpoints within your DLL.
Perform Access Control via the Remote User's IP Address:
This particular example limits access to a single IP address. It is obviously easier to set up a security rule in the configuration to provide this type of protection, but the example shows the basic components of writing an API Extension.
long AccessControlHook(void *parcel) { char ip[32]; ServerReadText(parcel, "Connect:/RemoteAddress", ip, sizeof(ip)); if (strcmp(ip, "12.34.56.78") != 0) { ServerWriteInteger(parcel, "Request:/StatusCode", 403); return HOOK_ERROR; } return HOOK_OK; }
The PowerWeb Server++ C/C++ Interface Function Definitions Are:
Return
ValueFunction
NameFunction
Parameterslong ServerGetConfig (void* parcel, void** handle); long ServerGetServer (void* parcel, void** handle); long ServerGetConnect (void* parcel, void** handle); long ServerGetRequest (void* parcel, void** handle); long ServerGetParameters (void* parcel, void** handle); long ServerGetArguments (void* parcel, void** handle); long ServerFind (void* parent, const char* pszName, void** item); long ServerKind (void* handle, unsigned long* type); long ServerSize (void* handle, unsigned long* size); long ServerName (void* handle, char* value, unsigned long size); long ServerFlush (void* handle); long ServerReadInteger (void* parent, const char* pszName, long* value); long ServerReadFloat (void* parent, const char* pszName, double* value); long ServerReadText (void* parent, const char* pszName, char* value, unsigned long size); long ServerReadBinary (void* parent, const char* pszName, unsigned char* value, unsigned long size); long ServerWriteInteger (void* parent, const char* pszName, long value); long ServerWriteFloat (void* parent, const char* pszName, double value); long ServerWriteText (void* parent, const char* pszName, const char* value); long ServerWriteBinary (void* parent, const char* pszName, const unsigned char* value, unsigned long size); long ServerAppendText (void* parent, const char* pszName, const char* value); long ServerAppendBinary (void* parent, const char* pszName, const unsigned char* value, unsigned long size); long ServerNewInteger (void* parent, const char* pszName, long value); long ServerNewFloat (void* parent, const char* pszName, double value); long ServerNewText (void* parent, const char* pszName, const char* value); long ServerNewBinary (void* parent, const char* pszName, const unsigned char* value, unsigned long size); long ServerNewList (void* parent, const char* pszName); long ServerNewSemaphore (void* parent, const char* pszName); long ServerDelete (void* handle); long ServerParent (void* here, void** handle); long ServerChild (void* here, void** handle); long ServerSibling (void* here, void** handle); - ServerInterpret (void* parcel, const char* code);
Parameters:
void* parcel
The parcel pointer is the same one that was passed to the API hook from PowerWeb Server++. It should be treated as a "magic cookie" which identifies the current context. The parcel is unique within the system, and allows for easy and safe multi-threading.
void** handle
The handle pointer is another "magic cookie", this time one that refers to a specific PowerWeb variable directory or individual variable. It is used to query a specific variable or to navigate through the hierarchy. It is a pointer to a pointer to allow PowerWeb to write the value of the handle pointer into it.
void* parent
The parent pointer is either the "parcel" pointer or a "handle" pointer. When the pszName contains a fully qualified global name (ie. has a prefix of "Request:/", "Server:/", etc) then the "parent" pointer is the "parcel" pointer, otherwise the pszName is a relative reference to a "handle" pointer.