W-PuTTY-CD Documents

Home | Licence | AcknowledgementFAQ | Docs | Download | Feedback | Changes | Wishlist | Team
Visit PuTTY Site | PuTTY Download | PuTTY Mirrors | PuTTY FAQ | Related Links | PuTTY Team

This Site in Under Construction and Revision

 

Till now the W-PuTTY-CD Documentation is under development, but till developed you can reference this page, also the comments in wputtycd.h and the comments header of the APIs in wputtycd.c


How it looks in Multi Sessions

W-PuTTY-CD Running 41 Concurrent Sessions, all listing Linux File System

N.B. The above two captures are a print screen of OpenTerm version 3.33, the first W-PuTTY-CD enabled program.  W-PuTTY-CD enabled program are programs using W-PuTYY-CL routines to load "WPuTTYCD.DLL" if it is installed.


I was using OpenTerm version 3.33 and its entire testing platform as a development environment for W-PuTTY-CD,  also Simon Tatham makes all PuTTYs resources available to me, see the Acknowledgment page.

In few words, OpenTerm was designed in 1991, during this time period, you need to purchase a third party TCP/IP protocol stack for windows, as FTP TCP/IP or Wollongong TCP/IP, in order to solve this problem, OpenTerm design team, including me, designed a loadable communication drivers interface, in order to add protocol stacks for every third part TCP/IP without modifying OpenTerm itself.

OpenTerm was ported from windows 16-bit to windows 32-bit then to all other versions of windows till windows Vista and windows 2008, keeping on this loadable driver interface.

Not only the communication drivers are designed to be loadable, but also the terminal modules, and file transfer modules, the User Control Command Modules, also the BiDi engine loads the RTL rules.

In order to handle all discrepancies between different implementations of the TCP/IP stacks vendors at this time, OpenTerm drivers interface is a very complicated one, it is not published but you can get it after signing a non disclosure agreement with OpenSys, Egypt. In few words, it is not based on functions only, but also handles transfer of events in-between the program and the communication drivers. All of us know that during the period from 1988 till 1995 terminal emulators worth huge investments.

When I was designing the W-PuTTY-CD interface, I was designing a very simple interface, in order to, simplify using it by developers and to keep on most of the PuTTYs code unchanged. One of my requirements is not to split the PuTTYs code, one for PuTTY and another one for W-PuTTY-CD.  Also keeping in mind, the future development of the C++ wrapper class and an OCX, which will encapsulate W-PuTTY-CD.

So I build an OpenTerm Communication driver for the purpose of developing and testing the W-PuTTY-CD DLL, this driver maps between OpenTerm interface and W-PuTTY-CD interface, also this driver uses W-PuTTY-CD loader to load W-PuTTY-CD "wputtycd.dll" if available, what makes OpenTerm the first W-PuTTY-CD enabled program. Following the next section is a sample of the mapping module impeded in this developed drive, after removing all OpenTerm specific parts of code.

Finally, what makes me developed W-PuTTY-CD are:

1.       Proving my concept of "ServEnt Threads", that makes the PuTTYs code runs unlimited number of concurrent connections with host computers.

2.       I respect the PuTTYs code and Simon Tatham method of coding, Simon is more than a professional, and as one of the professionals in this industry, I believe that his implementation of the SSH protocol must be more popular than using it only by PuTTY or its variants.

3.       The PuTTYs code and the "W" and "CD" code, both can be very good educational source codes, for computer engineering and computer science students.

4.       I believe that, till now, a lot peoples interested with Unix, like me, still want to use its text mode, the word hold more than 6.5 billions, still some of them interested with text terminals like me.

Note: Don't statically link with WPuTTYCD.DLL, always use the loader for this purpose, always keep in mind that we may add a new APIs, or change the ordinal numbers.


 

#include <windows.h>          /* For all windows files */

#include "wputtycl.h"             /* Header File for W-PuTTY-CD Loader. */

 

typedef LPVOID INSTANCE;

typedef LPVOID PISETTINGS;

 

typedef struct COMSTRMSET_TAG {

WPCD_SesCfg PtySesCfg;     /* Putty Session the hFrontEnd Settings. */

/* Other data you want to save */

} COMSTRMSET,  * PCOMSTRMSET;

 

 

/* Communication Stream Structure (Stream Descriptor). */

typedef struct COMSTRM_TAG {

LPCVOID Sid;                       /* Session Identifier, use a pointer to your global session data structure. */

HWND hWnd;                        /* Session window Handle. */

WORD Flags;                         /* Stream Status Flags. */

COMSTRMSET Settings;       /* Stream Settings. */

INSTANCE pPtySes;             /* Putty Session the hFrontEnd. */

/* You can save other data relevant to this connection, or session */

} COMSTRM, * PCOMSTRM;      

 

static TCHAR TempBuf1[TEMP_BUF_LEN];     /* Use it when you want memory. */

static TCHAR TempBuf2[TEMP_BUF_LEN];     /* Use it when you want memory. */

static int iNoConnectedSessions = 0;

 

static void ErrorBox(PCOMSTRM pcStrm, int errid);

 

extern HINSTANCE CDhInst;

 

/*======================================================================*\

* Function: Prtcl_Init

* Purpose: Called at driver or program start up.

* Parameters: NOTHING.

* Return: TRUE or FLASE, if FLASE Driver is unloaded.

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_Init(void)

{

HWND hWndMainProg;

int iRet = WPCL_LoadWPuTTYCD();

if (!iRet) return FALSE;

iRet = WPCL_Init();

hWndMainProg = (HWND)MyGetMainWindowFn();

/* Set Default HWND */

WPCL_SetDefaultWindow(hWndMainProg);

/* Set Default Notify Mode */

// WPCL_SetDefaultNotifyMode(WPCD_NOTIFY_RELAXED);

WPCL_SetDefaultNotifyMode(WPCD_NOTIFY_CONSTRAINED);

/* Set Default Notify Function */

WPCL_SetDefaultEvent(EVENT_NOTIFY_FUNC, (LPARAM)Prtcl_NotifyFunc);

/* Set Default Notify Message */

WPCL_SetDefaultEvent(EVENT_NOTIFY_MSG, MY_NOTIFYEVENT);

/* Disable function notify;

 * don't try to use function notify unless you know all details about how windows handles threads,

 * I built his function _Only_ as I need it for the C++ wrapper class && the OCX.

 */

WPCL_SetDefaultEvent(EVENT_NOTIFY_FUNC, 0);

/* Disable messgae notify */

// WPCL_SetDefaultEvent(EVENT_NOTIFY_MSG, 0);

/* Set Default Asynchronous Net Event Message */

WPCL_SetDefaultEvent(EVENT_ASYNC_NET, MY_ASYNC_NETEVENT);

/* Set Default Agent Callback Message */

WPCL_SetDefaultEvent(EVENT_AGNTCALLBK, MY_AGENT_CALLBACK);

/* Set Default Timer ID */

WPCL_SetDefaultEvent(EVENT_TIMER_ID, MY_TIMERID);

return iRet;

}

 

/*======================================================================*\

* Function: Prtcl_Shutdown

* Purpose: Called before driver or program release.

* Parameters: NOTHING.

* Return: TRUE or FLASE

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_Shutdown(void)

{

int iRet = WPCL_Shutdown();

iRet += WPCL_FreeWPuTTYCD();

return (iRet == 0);

}

 

/*======================================================================*\

* Function: Prtcl_QueryDefaults

* Purpose: Query protocol default settings.

* Parameters:

*     pCDSetBuf: Settings buffer.

* Return: TRUE or FALSE

* GVA: NOTHING.

\*======================================================================*/

int

Prtcl_QueryDefaults(PISETTINGS pCDSetBuf)

{

if (pCDSetBuf == NULL) return 0;

return (WPCL_QueryDefaults(&(((PCOMSTRMSET)pCDSetBuf)->PtySesCfg)) > WPCD_NOERROR);

}

 

/*======================================================================*\

* Function: CD_SetDefaults

* Purpose: Set Protocol default settings.

* Parameters:

*     pCDSetBuf: Protocol setting buffer.

* Return: TRUE or FALSE

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_SetDefaults(PISETTINGS pCDSetBuf)

{

if (pCDSetBuf == NULL) return FALSE;

return (WPCL_SetDefaults(&(((PCOMSTRMSET)pCDSetBuf)->PtySesCfg)) > WPCD_NOERROR);

}

 

/*======================================================================*\

* Function: Prtcl_DefaultsSetup

* Purpose: Change protocol default settings through setup dialogs.

* Parameters:

*     hWndParent: Parent window handle.

* Return: TRUE or FALSE

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_DefaultsSetup(HWND hWndParent)

{

return (WPCL_DefaultsSetup(hWndParent, FALSE) >= WPCD_NOERROR);

}

 

/*======================================================================*\

* Function: Prtcl_CreateInstance

* Purpose: This function Creates a communication Stream, call when creating a new session.

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

* Return: Return The Communication Instance Handle.

* GVA: NOTHING.

\*======================================================================*/

INSTANCE

Prtcl_CreateInstance(PCOMSTRM pcStrm, PISETTINGS pComSetBuf)

{

INSTANCE pPtySes;

if (pcStrm == NULL) return NULL;

pPtySes = WPCL_CreateInstance(

pcStrm,

(pComSetBuf == NULL) ? NULL : &(((PCOMSTRMSET)pComSetBuf)->PtySesCfg)

);

if (pPtySes == NULL) {

ErrorBox(pcStrm, WPCL_GetLastError());

}

return pcStrm->pPtySes = pPtySes;

}

 

/*======================================================================*\

* Function: Prtcl_DestroyInstance

* Purpose: Destroy the instance, call at session close.

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

* Return: TRUE or FALSE

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_DestroyInstance(PCOMSTRM pcStrm)

{

if (pcStrm == NULL) return FALSE;

return (WPCL_DestroyInstance(pcStrm->pPtySes) == WPCD_NOERROR);

}

 

/*======================================================================*\

* Function: Prtcl_QueryInstance

* Purpose: Query instance settings.

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

*     pComSetBuf: Settings, if NULL retrun default settings.

* Return: TRUE or FALSE

* GVA: NOTHING.

\*======================================================================*/

int

Prtcl_QueryInstance(PCOMSTRM pcStrm, PISETTINGS pComSetBuf)

{

if (pcStrm == NULL) return FALSE;

return (

WPCL_QueryInstance(

pcStrm->pPtySes,

(pComSetBuf == NULL) ? NULL : &(((PCOMSTRMSET)pComSetBuf)->PtySesCfg)

) > WPCD_NOERROR

);

}

 

/*======================================================================*\

* Function: Prtcl_SetInstance

* Purpose: Set an instance before Connect

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

* pComSetBuf: Settings, if NULL use defaults.

* Return: TRUE or FALSE.

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_SetInstance(PCOMSTRM pcStrm, PISETTINGS pComSetBuf)

{

if (pcStrm == NULL) return FALSE;

return (

WPCL_SetInstance(

pcStrm->pPtySes,

(pComSetBuf == NULL) ? NULL : &(((PCOMSTRMSET)pComSetBuf)->PtySesCfg)

) > WPCD_NOERROR

);

}

 

/*======================================================================*\

* Function: Prtcl_Setup

* Purpose: Setup current stream, If not opened display setup && connect dialog

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

* Return:  TRUE or FLASE

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_Setup(PCOMSTRM pcStrm)

{

if (pcStrm == NULL) return FALSE;

if (IS_OPENED(pcStrm->Flags)) {

int iRet;

iRet = WPCL_Setup(pcStrm->pPtySes, pcStrm->hWnd);

if (iRet == WPCD_NOERROR) {

return TRUE;

}

else if (iRet == WPCD_USER_CANCELED) {

return FALSE;

}

else {

ErrorBox(pcStrm, iRet);

return FALSE;

}

}

else {

return Prtcl_Connect(pcStrm);

}

}

 

/*======================================================================*\

* Function: Prtcl_Connect

* Purpose: Accept user input/settings then Connect to host.

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

* Return: TRUE or FLASE

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_Connect(PCOMSTRM pcStrm)

{

int iRet;

if (pcStrm == NULL) return FALSE;

if (Prtcl_IsConnected(pcStrm)) return FALSE;

RESET_FLAGS(pcStrm->Flags);

pcStrm->bUserDisconnect = FALSE;

if (WPCL_IsCfgDefaults(pcStrm->pPtySes)) {

WPCL_SetTermType(pcStrm->pPtySes, MyQueryTelnetTermType(pcStrm->Sid));

}

iRet = WPCL_Connect(pcStrm->pPtySes, pcStrm->hWnd);

if (iRet == WPCD_NOERROR) {

RESET_ERR(pcStrm->Flags);

/* Activate the connected session windows, assuming your program is an MDI application. */

SendMessage(                                                  // returns LRESULT in lResult

(HWND) GetParent(pcStrm->hWnd),    // handle to destination control

(UINT) WM_MDIACTIVATE,             // message ID

(WPARAM) pcStrm->hWnd,                 // = (WPARAM) (HWND) wParam;

(LPARAM) 0                                         // = (LPARAM) (0) lParam;

);

SET_OPENED(pcStrm->Flags); // Temporary set open flag

return TRUE;

}

else if (iRet == WPCD_BUSY) {

SET_ERR(pcStrm->Flags);

ErrorBox(pcStrm, WPCD_BUSY);

}

else if (iRet == WPCD_USER_CANCELED) {

}

else {

SET_ERR(pcStrm->Flags);

ErrorBox(pcStrm, iRet);

MySoundPlayEvent(SOUND_CONNECT_FAILED);

}

return FALSE;

}

 

/*======================================================================*\

* Function: Prtcl_IsConnected

* Purpose: Check if the communication stream is connected or not.

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

* Return: TRUE or FLASE

* GVA: NOTHING.

\*======================================================================*/

BOOL Prtcl_IsConnected(PCOMSTRM pcStrm)

{

if (pcStrm == NULL) return FALSE;

/*

* must be IS_OPENED() not IS_CONNECTED(),

* this Fools the menus systems status till connection succeed or failed

*/

return IS_OPENED(pcStrm->Flags);

}

 

/*======================================================================*\

* Function: Prtcl_DisConnect

* Purpose: Disconnect this stream from host.

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

* Return: TRUE or FLASE

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_DisConnect(PCOMSTRM pcStrm)

{

int ret, iDisConnectRetries;

if (pcStrm == NULL) return FALSE;

 

#define DISCONNECT_MORE_RETRY 3

 

iDisConnectRetries = 0;

do {

ret = WPCL_DisConnect(pcStrm->pPtySes);

if (!((ret == WPCD_IN_PROGRESS) || (ret == WPCD_WOULD_BLOCK))) break;

} while (++iDisConnectRetries < DISCONNECT_MORE_RETRY);

if (ret == WPCD_NOERROR) {

RESET_FLAGS(pcStrm->Flags);

MySoundPlayEvent(SOUND_DISCONNECT_OK);

}

else if ((ret == WPCD_WOULD_BLOCK) || (ret == WPCD_IN_PROGRESS)) {

SET_ERR(pcStrm->Flags);

ErrorBox(pcStrm, ret);

}

else {

SET_ERR(pcStrm->Flags);

ErrorBox(pcStrm, ret);

MySoundPlayEvent(SOUND_DISCONNECT_FAILED);

return FALSE;

}

return TRUE;

}

 

/*======================================================================*\

* Function: Prtcl_Send

* Purpose: Send data in buffer through this communication stream.

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

*     pBuf : Buffer to send.

*     iBufLen: Buffer length.

* Return: -1 if error, or the number of bytes sent.

* GVA: NOTHING.

\*======================================================================*/

int

Prtcl_Send(PCOMSTRM pcStrm, LPCBYTE pBuf, int iBufLen)

{

int iRet;

if (!IS_CONNECTED(pcStrm->Flags)) return 0;

iRet = WPCL_ComWrite(pcStrm->pPtySes, pBuf, iBufLen);

return (iRet < WPCD_NOERROR) ? -1 : iRet;

}

 

/*======================================================================*\

* Function: Prtcl_SendStr

* Purpose: Send a string through this communication stream.

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

*     pStr: Null terminated string to send.

* Return: -1 if error, or the number of bytes sent.

* GVA: NOTHING.

\*======================================================================*/

int

Prtcl_SendStr(PCOMSTRM pcStrm, LPCSTR pStr)

{

int iRet;

if (!IS_CONNECTED(pcStrm->Flags)) return 0;

iRet = WPCL_SendStr(pcStrm->pPtySes, pStr);

return (iRet < WPCD_NOERROR) ? -1 : iRet;

}

 

/*======================================================================*\

* Function: Prtcl_Recv

* Purpose: Receive data from this communication stream.

* Parameters:

*     pcStrm: Pointer Communication Stream Structure (Descriptor).

*     pBuf: Buffer to receive into.

*     iBufLen: Buffer length.

* Return: Received length.

* GVA: NOTHING.

\*======================================================================*/

int

Prtcl_Recv(PCOMSTRM pcStrm, LPBYTE pBuf, int iBufLen)

{

int iRet;

if (!IS_CONNECTED(pcStrm->Flags)) return 0;

iRet = WPCL_ComRead(pcStrm->pPtySes, pBuf, iBufLen);

return (iRet < WPCD_NOERROR) ? 0 : iRet;

}

 

/*======================================================================*\

* Function: Prtcl_SendCmd

* Purpose: Send one of the protocol commands,

* after displaying a dialog to select one of the commands

* Parameters:

*     pcStrm: Pointer to the Communication Stream Structure (Descriptor).

* Return: TRUE if no error.

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_SendCmd(PCOMSTRM pcStrm)

{

if (!IS_OPENED(pcStrm->Flags)) return FALSE;

return (WPCL_SendSpecialCmd(pcStrm->pPtySes, NULL) == WPCD_NOERROR);

}

 

/*======================================================================*\

 * Function: Prtcl_SendBreak

* Purpose: Send the Protocol break command.

* Parameters:

*     pcStrm: Pointer to the Communication Stream Structure (Descriptor).

* Return: TRUE if no error.

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_SendBreak(PCOMSTRM pcStrm)

{

if (!IS_OPENED(pcStrm->Flags)) return FALSE;

return (WPCL_SendBreak(pcStrm->pPtySes) == WPCD_NOERROR);

}

 

/*======================================================================*\

* Function: Prtcl_GetErrorMsg

* Purpose: This function ....

* Parameters:

*     errid: error number.

*     lpszBuffer: address of buffer to fill with the message.

*     cbBuffer: size of buffer.

* Return: Error message length.

* GVA: NOTHING.

\*======================================================================*/

static

int

Prtcl_GetErrorMsg(

int errid,                     /* Error Number. */

LPSTR lpszBuffer,     /* address of buffer for resource */

int cbBuffer                /* size of buffer */

) {

UINT idRes;

int ret;

switch (errid) {

/*====================== W-PuTTY-CD Errors =======================*/

case WPCD_NOTINITIALISED: /* not initialized. */

idRes = IDS_WPCD_NOTINITIALISED;

break;

case WPCD_INVALID_HANDLE: /* invalid handle. */

idRes = IDS_WPCD_INVALID_HANDLE;

break;

case WPCD_INVALID_PARAMETER: /* invalid parameter. */

idRes = IDS_WPCD_INVALID_PARAMETER;

break;

case WPCD_IN_PROGRESS: /* operation now in progress */

idRes = IDS_WPCD_IN_PROGRESS;

break;

case WPCD_ALREADY_CONNECTED: /* already connected. */

idRes = IDS_WPCD_ALREADY_CONNECTED;

break;

case WPCD_NOT_CONNECTED: /* not connected. */

idRes = IDS_WPCD_NOT_CONNECTED;

break;

case WPCD_CONNECTION_CLOSED: /* connection closed. */

idRes = IDS_WPCD_CONNECTION_CLOSED;

break;

case WPCD_REMOTE_EXIT: /* remote host close conn. */

idRes = IDS_WPCD_REMOTE_EXIT;

break;

case WPCD_CONNECT_ERROR: /* error while connecting. */

idRes = IDS_WPCD_CONNECT_ERROR;

break;

case WPCD_NOCONN_EXCEEDED: /* No connection exceeded. */

idRes = IDS_WPCD_NOCONN_EXCEEDED;

break;

case WPCD_NETWORK_DOWN: /* network is down. */

idRes = IDS_WPCD_NETWORK_DOWN;

break;

case WPCD_BUSY: /* busy, try later. */

idRes = IDS_WPCD_BUSY;

break;

case WPCD_WOULD_BLOCK: /* function would block. */

idRes = IDS_WPCD_WOULD_BLOCK;

break;

case WPCD_TIMEOUT: /* timeout, try again. */

idRes = IDS_WPCD_TIMEOUT;

break;

case WPCD_USER_CANCELED: /* user cancelled. */

idRes = IDS_WPCD_USER_CANCELED;

break;

case WPCD_INTERNAL_ERROR: /* internal error. */

idRes = IDS_WPCD_INTERNAL_ERROR;

break;

case WPCD_MEM_ERROR: /* memory error. */

idRes = IDS_WPCD_MEM_ERROR;

break;

case WPCD_CRC_ERROR: /* crc error. */

idRes = IDS_WPCD_CRC_ERROR;

break;

case WPCD_FATAL_ERROR: /* fatal error. */

idRes = IDS_WPCD_FATAL_ERROR;

break;

case WPCD_SYSTEM_ERROR: /* system error. */

idRes = IDS_WPCD_SYSTEM_ERROR;

break;

case WPCD_UNKNOWN_ERROR: /* unkown reason for error. */

idRes = IDS_WPCD_UNKNOWN_ERROR;

break;

/*======================== Loader Errors =========================*/

case WPCL_INTERNAL_ERROR: /* Loader internal error. */

idRes = IDS_WPCL_INTERNAL_ERROR;

break;

case WPCL_MEM_ERROR: /* Loader memory error. */

idRes = IDS_WPCL_MEM_ERROR;

break;

case WPCL_CRC_ERROR: /* Loader crc error. */

idRes = IDS_WPCL_CRC_ERROR;

break;

case WPCL_FATAL_ERROR: /* Loader fatal error. */

idRes = IDS_WPCL_FATAL_ERROR;

break;

case WPCL_SYSTEM_ERROR: /* Loader system error. */

idRes = IDS_WPCL_SYSTEM_ERROR;

break;

case WPCL_UNKNOWN_ERROR: /*Loader unknown reason for err*/

idRes = IDS_WPCL_UNKNOWN_ERROR;

break;

default:

idRes = IDS_DEFAULT;

break;

}

ret = LoadString(CDhInst, idRes, lpszBuffer, cbBuffer);

if (!ret) {

wsprintf(lpszBuffer, "Error Number %d", errid);

}

return ret;

}

 

/*======================================================================*\

* Function: ErrorBox

* Purpose: This function ....

* Parameters:

* pcStrm: Pointer to the Communication Stream Structure (Descriptor).

* errid: error number.

* Return: NOTHING.

* GVA: TempBuf1, TempBuf2.

\*======================================================================*/

static

void

ErrorBox(PCOMSTRM pcStrm, int errid)

{

TempBuf1[0] = TempBuf2[0] = 0;

Prtcl_GetErrorMsg(errid, TempBuf1, TEMP_BUF_LEN);

LoadString(CDhInst, IDS_ERRORCAPTION, (LPTSTR)TempBuf2, TEMP_BUF_LEN);

MessageBox(pcStrm->hWnd, (LPTSTR)TempBuf1,

(LPTSTR)TempBuf2, MB_APPLMODAL|MB_OK|MB_ICONSTOP);

}

 

/*======================================================================*\

* Function: Prtcl_TimerActivation

* Purpose: Timer Event Handler

* Parameters:

*     pcStrm: Pointer to the Communication Stream Structure (Descriptor).

* Return: TRUE or FLASE

* GVA: NOTHING.

\*======================================================================*/

BOOL

Prtcl_TimerActivation(PCOMSTRM pcStrm)

{

/*

 * In you session window message loop you must handle this message as follows:

 *    case WM_TIMER:

 *        if (wParam == MY_TIMERID) return Prtcl_TimerActivation(pcStrm);

 *       else return MyOtherTimersHandlers();

 */

return (WPCL_TimerActivation(pcStrm->pPtySes) == WPCD_NOERROR);

}

 

/*======================================================================*\

* Function: Prtcl_NotificationHandler

* Purpose: Protocol Notifications Handler

* Parameters:

*     pcStrm: Pointer to the Communication Stream Structure (Descriptor).

*     wParam: Notification message wParam

*     lParam: Notification message lParam

* Return: TRUE or FLASE

* GVA: NOTHING.

\*======================================================================*/

static

BOOL

Prtcl_NotificationHandler(PCOMSTRM pcStrm, WPARAM wParam, LPARAM lParam)

{

switch (wParam) {

case WPCN_SESCONNECT: /* session connected. */

if (lParam) {

/* Session succeed to connect */

++iNoConnectedSessions;

MySoundPlayEvent(SOUND_CONNECT_OK);

SET_CONNECTED(pcStrm->Flags);

SET_OPENED(pcStrm->Flags);

RESET_ERR(pcStrm->Flags);

}

else {

/* Session failed while connecting */

MySoundPlayEvent(SOUND_CONNECT_FAILED);

RESET_CONNECTED(pcStrm->Flags);

RESET_OPENED(pcStrm->Flags);

SET_ERR(pcStrm->Flags);

}

return TRUE;

 

case WPCN_SESDATAREADY: /* session data ready. */

switch(lParam) {

case WPCN_HOSTNAME:

{

#define MAX_CAPTION 1024

LPCTSTR pRealHost = WPCL_GetRealHostName(pcStrm->pPtySes);

if (pRealHost != NULL) {

TCHAR szNewCaption[MAX_CAPTION];

wsprintf(szNewCaption, "%s (%s)", (LPCTSTR)MyGetSessionNameFn(), pRealHost);

SetWindowText(pcStrm->hWnd, szNewCaption);

}

}

return TRUE;

 

case WPCN_SPECIALSMENU:     /* new specials menu ready */

case WPCN_HOSTDATA:              /* new data from host. */

default:

return TRUE;

}

 

case WPCN_SESDISCONNECT:             /* session disconnected. */

if (lParam) {

/* User disconnect request succeed */

}

else {

/* User disconnect request failed */

}

break;

 

case WPCN_CRITICAL:                           /* critical condition. */

/* Handle Critical conditions, as disabling program exit, session close, .... */

break;

 

case WPCN_SETCHANGE:                     /* settings changed. */

if (lParam) {

COMSTRMSET OldSettings;          /* Old Stream Settings. */

OldSettings = pcStrm->Settings;       /* Save old Settings. */

/* Query Settings after change */

WPCL_QueryInstance(pcStrm->pPtySes, &pcStrm->Settings.PtySesCfg);

/* Record Settings after change */

MySettingsChangeHandler(pcStrm, &OldSettings);

}

break;

 

case WPCN_BUSY:                               /* busy status. */

/* Display busy sign */

break;

 

case WPCN_FATAL:                             /* fatal condition. */

SET_ERR(pcStrm->Flags);

break;

 

case WPCN_RETRY:                             /* retry count in LPARAM. */

break;

 

case WPCN_CLEARSELECT:               /* clear selection. */

/* Clear session selected data if any */

break;

 

case WPCN_PENDINGCLOSE:           /* session waiting 4 close */

/* Display busy sign */

break;

 

case WPCN_REMOTEEXIT:               /* session remotely closed.*/

RESET_CONNECTED(pcStrm->Flags);

break;

 

case WPCN_SESABORTED:              /* session forced to close */

case WPCN_SESCLOSED:                 /* session closed. */

case WPCN_SESDESCLOSED:          /* session closed by user. */

if (lParam) {

if (iNoConnectedSessions > 0) --iNoConnectedSessions;

RESET_CONNECTED(pcStrm->Flags);

RESET_OPENED(pcStrm->Flags);

SetWindowText(pcStrm->hWnd, (LPCTSTR)MyGetSessionNameFn());

if (wParam != WPCN_SESDESCLOSED) {

/* Connection closed from remote side, not by user request.

 * call you session remote disconnect handler to close the session, reconnect it, ...... 

 */

MySessionDisCloseHandler();

}

RESET_ERR(pcStrm->Flags);

return TRUE;

}

else {

if (wParam == WPCN_SESABORTED) {

/* Session is aborted before start, this is a rare condition */

}

else {

/* Session is closed or Disconnected by user but if this handler is called by the notify function

* it is still _unsafe_ to call windows user functions that send messages.

*/

}

}

break;

 

default:

break;

}

return TRUE;

}

 

/*======================================================================*\

* Function: Prtcl_NotifyFunc

* Purpose: W-PuTTY-CD events notification function

* Parameters:

*     pPtySes: W-PuTTY-CD FrontEnd handle

*     dwpcStrm: called supplied data SID

*     wParam: Notification message wParam

*     lParam: Notification message lParam

* Return: NOTHING.

* GVA: NOTHING.

\*======================================================================*/

void

CALLBACK

Prtcl_NotifyFunc(INSTANCE pPtySes, DWORD dwpcStrm, WPARAM wParam, LPARAM lParam)

{

PCOMSTRM pcStrm = (PCOMSTRM) dwpcStrm;

Prtcl_NotificationHandler(pcStrm, wParam, lParam);

return;

}

 

/*======================================================================*\

* Function: Prtcl_MessageHandler

* Purpose: Protocol Events Handler

* Parameters:

* pcStrm: Pointer to the Communication Stream Structure (Descriptor).

* others : as WindowProc

*     http://msdn.microsoft.com/en-us/library/ms633573.aspx

* Return: TRUE or FLASE

* GVA: NOTHING.

\*======================================================================*/

LRESULT

Prtcl_MessageHandler(

PCOMSTRM pcStrm,

HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam

) {

 

/*

 * In you session window message loop you must handle this messages as follows:

 *    case MY_NOTIFYEVENT:

 *    case MY_AGENT_CALLBACK:

 *    case MY_ASYNC_NETEVENT:

 *            return Prtcl_MessageHandler(pcStrm, hwnd, message, wParam, lParam);

 */

switch (message) {

case MY_NOTIFYEVENT:

return Prtcl_NotificationHandler(pcStrm, wParam, lParam);

 

case MY_AGENT_CALLBACK:

case MY_ASYNC_NETEVENT:

{

int iRet;

iRet = WPCL_EventHandler(pcStrm->pPtySes, hwnd, message, wParam, lParam);

return (iRet != WPCD_NOERROR);

}

 

default:

return TRUE;

}

}

 


 

This Site in Under Construction and Revision

This is another very simple way

int iRet = WPCL_LoadWPuTTYCD();

if (!iRet) {

Display Unable to Load W-PuTTY-CD Error;

return;

}

iRet = WPCL_Init();

if (!iRet) {

Display Unable to Initialize W-PuTTY-CD Error;

return;

}

WPCL_SetDefaultWindow(hWndMyPorgram);

WPCL_SetDefaultEvent(EVENT_NOTIFY_MSG, WM_MY_NOTIFY_MSG);

WPCL_SetDefaultEvent(EVENT_ASYNC_NET, WM_MY_ASYNC_NETEVENT_MSG);

WPCL_SetDefaultEvent(EVENT_AGNTCALLBK, WM_MY_AGNT_CALLBK_MSG);

WPCL_SetDefaultEvent(EVENT_TIMER_ID, MY_TIMER ID);

void * frontend;        // Your W-PuTTY-CD Session

/* MySid must be a unique identifier, try to use a pointer to your session global data structure

*/

frontend = WPCL_CreateInstance( MySid,  NULL);       

if (frontend == NULL) {

Dispaly Error;

return;

}

iRet = WPCL_Connect(frontend, hMySessionWnd);

if (iRet != WPCD_NOERROR) {

deal with error;

return;

}

While (My Session Is Running) {

if ((iRet = WPCL_ComRead(frontend, Buf, BufLen)) > 0)  {

Deal With Incoming data;

}

 

if ((iRet = WPCL_ComWrite(frontend, Buf, BufLen)) != BufLen)  {

Deal With Unsent data;

Deal With Errors;

}

 

if (!WPCL_IsConnected(frontend)) break;

}

if ((iRet = WPCL_DisConnect(frontend)) != WPCD_NOERROR) {

Dispaly Error;

}

 

if ((iRet = WPCL_DestroyInstance(frontend)) != WPCD_NOERROR) {

Dispaly Error;

}

 

iRet = WPCL_Shutdown();

iRet += WPCL_FreeWPuTTYCD();

return (iRet == 0);

 

 

In your windows message loop you must handle this messages

 

case WM_TIMER: {

if (TimerID == MY_TIMER ID) {

return (WPCL_TimerActivation(frontend) == WPCD_NOERROR);

}

other timers handling;

}

 

 

case WM_MY_ASYNC_NETEVENT_MSG: {

int iRet = WPCL_EventHandler(frontend, hwnd, message, wParam, lParam);

return (iRet != WPCD_NOERROR);

}

 


If you want to comment on this web site, or modify any of its contents
E-Mail: web@winputty.com