This section covers the following:
To create a valid TPH, we are required to have seven methods in our DLL even though some of them are not used by the GroupWise client. The reason the unused methods are required is because the methods that are used, are called from the GroupWise client by their exported order number. This is why they are required to be exported in a specific order. In C++, this is easily accomplished in the.DEF file. The following is a sample from a C++ .DEF file and also identifies the order in which the methods must be exported:
EXPORTS TPHVersion @1 Compatibility @2 TimeStamp @3 Entry @4 Exit @5 HandleToken @6 ValidateToken @7
In Delphi, you need to use the following code in the file that contains the TPH methods:
exports TPHVersion index 1 resident, Compatibility index 2 resident, TimeStamp index 3 resident, Entry index 4 resident, Exit index 5 resident, HandleToken index 6 resident, ValidateToken index 7 resident; begin end.
Below are skeletons of source code for all the required TPH methods, written in C++ and Delphi formats. These skeletons will be the basis for our example and we will add functionality to them as we go.
For C++, note that all the methods require the WINAPI specifier before the method name:
DWORD WINAPI TPHVersion ( void ) { return 0; }
DWORD WINAPI Compatibility( ATOM AppAtom, WORD AppVersion) { // Greater than or equal to GroupWise 5.2 if (5 >= LOBYTE(AppVersion) && 2 >= HIBYTE(AppVersion)) { return (DWORD) TRUE; } else { return (DWORD) FALSE; } }
DWORD WINAPI TimeStamp( void ) { return 0; }
WORD WINAPI Entry( WORD wLanguage) { if ('U' == (char) LOBYTE(wLanguage) && 'S' == (char)HIBYTE(wLanguage)) { return 1; } else { return 0; } }
WORD WINAPI Exit( void ) { return 1; }
int WINAPI HandleToken(LPTPH_RETURNVAL lpTokenData, HWND hLinkWnd, WORD msg ) { return DLL_HAN_NOT_HANDLED; }
DWORD WINAPI ValidateToken(LPMAC_TOKEN lpTokenData, Lpvoid lpDataTypeInfo) { return DLL_VAL_UNKNOWN_TOKEN; }
For Delphi, note that all the functions require the export and stdcall specifier after the parameter list:
Function TPHVersion: LongInt;export; stdcall; begin result := 0; end; Function Compatibility(AppName: ATOM; AppVersion: Word): LongInt; export; stdcall; begin if (5 >= LO(AppVersion) and 2 >= HI(AppVersion) then begin result := 1; end else begin result := 0; end; end; Function TimeStamp: LongInt; export; stdcall; begin result := 0; end; Function Entry(wLanguage: Word): SmallInt; export; stdcall; begin if ( 'U' = Chr(LO(wLanguage)) and 'S' = Chr(HI(wLanguage)) then begin result := 1; end else begin result := 0; end; end; Function Exit: SmallInt; export; stdcall; begin result := 1; end; Function HandleToken(lpTokenData: LPTPH_RETURNVAL; hLinkWnd: HWND; msg: Word): SmallInt; export; stdcall; begin result := SmallInt(DLL_HAN_NOT_HANDLED); end; Function ValidateToken(lpTokenData: LPMAC_TOKEN; lpDataTypeInfo: LPVOID): LongInt; export; stdcall; begin result := 0; end;