Category : Files from Magazines
Archive   : MSJV7_4.ZIP
Filename : SERVER.C

 
Output of file : SERVER.C contained in archive : MSJV7_4.ZIP
/****************************************************************************

PROGRAM: SERVER.C

PURPOSE: Contains Remote Browser Server routines. The Client
routines are in netio.c and browser.c

NOTE: The server has always only one pending NCB, be it
a Listen NCB or a Receive NCB. Hence, only one
client can connect to it at a time.

FUNCTIONS:
InitServer - Initializes the Server". After initialization,
any remote Client can contact the Server.
DeleteServer - Removes the Server. It cancels any pending
commands.
Server - A routine called during Windows Idle time
to allow server accomplish some chores
ListenCompleted- Called from browser.c when a pending
Listen completes.
ReceiveCompleted-Called from browser.c when a pending
Receive completes.
PostAListen - Simply posts a asynchronous Listen
PostAReceive - Simply posts a asynchronous Receive

History:
January, 1992 Alok Sinha Created

****************************************************************************/

// Includes
#include
#include "ncb.h"
#include "state.h"
#include "common.h"
#include "netio.h"
#include "wnetbios.h"


#include
#include
#include

/*
* Global data
*/
extern ServerFSM ServerState;
extern SendStatus enumSSendStatus;
extern char chLocalName[];
extern char chRemoteName[];
extern char szErrorBuffer[];
char chServerName [NETBIOS_NAME_LENGTH+1];
/*
* Local static data
*/

BYTE bNameNumS; /* Server Name Number in Name Table */
BYTE bLsnS ; /* LSN of the Server */
/* Server Name */

PNCB pncbListenNCB; /* Posted Listen */
LPSTR lpServerData; /* Server Receives Data Here */

#define SERVER_RECEIVE_SIZE (2048)
#define FILE_LEN (13)

char szDirectory [ _MAX_DIR ];

extern VOID CopyName( char *pchLocalName, char *pchBuffer );
/*
* Internal functions
*/

BYTE PostAReceive ( HWND hwnd);
BYTE PostAListen ( HWND hwnd );

/****************************************************************************

FUNCTION: InitServer()

PURPOSE: Initialize the Server. In this sample application, we
only have a single Listen pending at a time. We keep
a pointer to Listen NCB in static memory while Listen
NCB itself is in fixed memory.

****************************************************************************/

VOID InitServer ( HWND hwndMain )
{
BYTE bRc;

// Delete any old connection and name if existing
if ( ServerState != S_UNINITIALIZED)
DeleteServer( );

// Create a Server name from the local name. Recall, local name
// is already blank padded.
memcpy ( chServerName, chLocalName, NETBIOS_NAME_LENGTH + 1);
chServerName [NETBIOS_NAME_LENGTH - 1] = SERVER_NAME_END;

// Set the Server back to uninitialized state
ServerState = S_UNINITIALIZED;

if ((bRc = AddName((LPSTR)chServerName,
&bNameNumS)) != NO_ERROR)
{
sprintf(szErrorBuffer,
"Error Adding Server Name [%s] Error [%x]",
chServerName,
bRc
);

MessageBox(hwndMain, (LPSTR)szErrorBuffer,
"Error", MB_OK);

return ;

}
else
ServerState = S_INITIALIZED;

/*
* Now, post a async. LISTEN
*/

if ((bRc = PostAListen( hwndMain)) != NRC_PENDING)
return ;
else
ServerState = S_LISTENING;

return ;

}

/****************************************************************************

FUNCTION: DeleteServer()

PURPOSE: Delete the Server. Since, we can either have a Listen
pending or a Receive pending, cleanup is easy.

****************************************************************************/

VOID DeleteServer( )
{

if (ServerState >= S_CONNECTED)
{
Hangup(bLsnS);
bLsnS = 0;
NcbFree ( (LPVOID) lpServerData); // Free the Previously Allocated Buffer
}
else if (ServerState == S_LISTENING)
{
Cancel(pncbListenNCB);
NcbFree( (LPVOID) pncbListenNCB);
}

if ( ServerState >= S_INITIALIZED)
{
(void) DeleteName( (LPSTR) chServerName, bNameNumS);
bNameNumS = 0;
}

ServerState = S_UNINITIALIZED;
return ;

}


/****************************************************************************

FUNCTION: Server()

PURPOSE: This gets called during Window Idle Time. We can do
Server specific chores here.

****************************************************************************/

VOID Server(HWND hwndMain )
{

/*
* In this example, we do not do anything
*/

;

}

/****************************************************************************

FUNCTION: ListenCompleted()

PURPOSE: This gets called when a Listen is completed. Once
a Listen completes, we need to either issue
a Receive or just re-issue a Receive. In this
sample, only one Receive can be posted at a time.

'hwndMain' has the window handle to originating window
and 'pncbNCB' has pointer to just completed NCB.

****************************************************************************/

VOID ListenCompleted( HWND hwndMain, PNCB pncbNCB)
{
BYTE bRc;
BOOL fNcbFreed = FALSE;

// First find out if we timeout or error-ed out
if (pncbNCB->ncb_cmd_cplt == NRC_CMDTMO)
{
NcbFree ( (LPVOID) pncbNCB);
fNcbFreed = TRUE;

/*
* Now, post a async. LISTEN again
*/
if ((bRc = PostAListen( hwndMain)) == NRC_PENDING)
ServerState = S_LISTENING;
return;
}
else if (pncbNCB->ncb_cmd_cplt == NRC_GOODRET)
{
// Somebody connected to us. Save the local session number
// and update UI.
bLsnS = pncbNCB->ncb_lsn;
_fmemcpy ( (LPVOID) chRemoteName,
pncbNCB->ncb_callname,
NETBIOS_NAME_LENGTH
);
chRemoteName [ NETBIOS_NAME_LENGTH + 1] = '\0';
PostMessage (hwndMain, CLIENT_CONNECTED, 0, 0);

// Free the NCB
NcbFree ( (LPVOID) pncbNCB);
fNcbFreed = TRUE;

ServerState = S_CONNECTED;
// Now hang out a receive
if ((bRc = PostAReceive ( hwndMain)) == NRC_PENDING)
{
ServerState = S_RECEIVING;
return;
}
else
{
/*
* Go back to LISTENing
*/
if ((bRc = PostAListen( hwndMain)) == NRC_PENDING)
{
ServerState = S_LISTENING;
return;
}
// else go down to debug print out
}
}

// We should never come here. Show error for debugging purposes

sprintf(szErrorBuffer,
"Error [%d] in ListenComplete\n Aborting Hanging Listen\n Close Program",
pncbNCB->ncb_cmd_cplt
);
MessageBox(hwndMain, (LPSTR)szErrorBuffer,"Error", MB_OK);

if (fNcbFreed = FALSE)
NcbFree ( (LPVOID) pncbNCB);

}

/****************************************************************************

FUNCTION: ReceiveCompleted()

PURPOSE: This gets called when a Receive is completed.
If Receive simply time-ed out, we need
to post another Receive. If Client hang-up on
us, then we need to go back to listen mode.
Else we need to service a Client who has Sent
some packet.

'hwndMain' has the window handle to originating window
and 'pncbNCB' has pointer to just completed NCB.

****************************************************************************/
VOID ReceiveCompleted( HWND hwndMain, PNCB pncbNCB)
{
BYTE bRc;
PACKET FAR *pacPtr;
char *pszBuffer;
LPSTR lpBuffer;
FINDFIRST FAR *pFindFirst;
FINDNEXT FAR *pFindNext;
FINDT findFileInfo;
FINDT FAR *pFindToSend;
BOOL fNcbFreed = FALSE;
char chFileName [ FILE_LEN ];




// First find out if we timeout or error-ed out
if (pncbNCB->ncb_cmd_cplt == NRC_CMDTMO)
{
NcbFree ( (LPVOID) pncbNCB); // Free the Receive NCB
NcbFree ( (LPVOID) lpServerData); // Free the Previously Allocated Buffer
fNcbFreed = TRUE;
/*
* Now, post a async. RECEIVE again
*/
if ((bRc = PostAReceive( hwndMain)) == NRC_PENDING)
{
ServerState = S_RECEIVING;
return;
}
else
{ /*
* Some problem hanging receive. Abort Server Receives
* Go Back to Listening
*/
if ((bRc = PostAListen( hwndMain)) == NRC_PENDING)
{
ServerState = S_LISTENING;
return;
}
else // else go down to debug print
{
sprintf(szErrorBuffer, "Error upon Listen: %x", bRc);
MessageBox ( GetActiveWindow(), szErrorBuffer , "ReceiveCmplt", MB_OK);
}
}
}
else if ((pncbNCB->ncb_cmd_cplt == NRC_SCLOSED) ||
(pncbNCB->ncb_cmd_cplt == NRC_SABORT))
{
NcbFree ( (LPVOID) pncbNCB); // Free the Receive NCB
NcbFree ( (LPVOID) lpServerData); // Free the Previously Allocated Buffer
fNcbFreed = TRUE;

// Current Client hung up. So go back to listening
if ((bRc = PostAListen( hwndMain)) == NRC_PENDING)
{
ServerState = S_LISTENING;
return;
}
else // else go down to debug print
{
sprintf(szErrorBuffer, "Error when posting Listen: %x", bRc);
MessageBox ( GetActiveWindow(), szErrorBuffer , "ReceiveCmplt", MB_OK);
}
}
else if (pncbNCB->ncb_cmd_cplt == NRC_GOODRET)
{
/*
* Ahh! We received a packet, but first check size of packet
*/
ServerState = S_RECEIVED;
if ( pncbNCB->ncb_length < PACKET_SIZE)
{
NcbFree ( (LPVOID) pncbNCB);
NcbFree ( (LPVOID) lpServerData); // Free the Previously Allocated Buffer
fNcbFreed = TRUE;
/*
* Go back to RECEIVE again
*/
if ((bRc = PostAReceive( hwndMain)) == NRC_PENDING )
{
ServerState = S_RECEIVING;
return;
}
else
{ /*
* Some problem hanging receive. Abort Server Receives
* Go Back to Listening
*/
if ((bRc = PostAListen( hwndMain)) == NRC_PENDING)
{
ServerState = S_LISTENING;
return;
}
else // else go down to debug print
{
sprintf(szErrorBuffer, "Error when posting Listen: %x", bRc);
MessageBox ( GetActiveWindow(), szErrorBuffer , "ReceiveCmplt", MB_OK);
}
}
}

pacPtr = (PACKET FAR *) pncbNCB->ncb_buffer;

// What is the command?
switch (pacPtr->bCommand)
{

case R_GETCWD:
// Service the command i.e. SEND a packet
ServerState = S_SENDING;
// Allocate fixed memory
lpBuffer = (LPSTR) NcbAllocBuf( (DWORD) _MAX_DIR);

if ((pszBuffer = getcwd (NULL, _MAX_DIR)) == NULL)
{
// Send back made up directory
lpBuffer[0] = '.';
lpBuffer[1] = '\\';
}
else
{ // Send back real path information and free memory
// given by getcwd()

_fmemcpy ( lpBuffer, (LPVOID) pszBuffer, strlen(pszBuffer));
free ( pszBuffer );
}

bRc = Send ( hwndMain, // handle to send message to
lpBuffer, // Data to Send
_fstrlen(lpBuffer)+1, // Data buffer size
bLsnS, // Local Session Number
BW_S_SEND_BACK, // Message sent upon completion
&enumSSendStatus // A signal.
);

NcbFree ( (LPVOID) lpBuffer); // Release Buffer

if (bRc==NO_ERROR)
break;
else
{
MessageBox ( GetActiveWindow(),
"Error in Sending Data",
"GetCwd",
MB_OK);
break;
}
The caller specifies a buffer in 'lpData' and buffer
length in 'wDataLen'. The caller must also specify
the local session number in 'bLsn' which should be
valid. The caller specifies the message (in 'iMessage')
that post routine should send to the originating
window recognized by 'hWnd'. Finally, a variable
'peSendStatus' pointer must be provided.
The pointer 'peSendStatus' allows for "sender" to be a stack based variable as _dos_findfirst
// does not like global memory based variable

_fmemcpy ( (LPVOID) chFileName, pFindFirst->chFileName, FILE_LEN);
bRc = (BYTE) _dos_findfirst ( chFileName,
pFindFirst->uAttrib,
&findFileInfo
);
if (bRc)
{
// Send back made up information.
findFileInfo.size = -1;
}

_fmemcpy ( (LPVOID) pFindToSend,
(LPVOID) &findFileInfo,
sizeof (FINDT)
);
bRc = Send ( hwndMain, // handle to send message to
(LPSTR) pFindToSend, // Data to Send
sizeof(FINDT), // Data buffer size
bLsnS, // Local Session Number
BW_S_SEND_BACK, // Message sent upon completion
&enumSSendStatus // A signal.
);

NcbFree ( (LPVOID) pFindToSend); // Release Buffer


if (bRc==NO_ERROR)
break;
else
{
MessageBox ( GetActiveWindow(),
"Error in Sending Data",
"Dos_Find_First",
MB_OK
);
break;
}
case R_FINDNEXT:
// Service the command i.e. SEND a packet back
ServerState = S_SENDING;

pFindNext = (FINDNEXT FAR *) ( (LPSTR) pacPtr + sizeof ( BYTE));
// Allocate fixed memory
pFindToSend = (FINDT FAR *) NcbAllocBuf( (DWORD) sizeof (FINDT));
if ( (pFindNext == NULL) || (pFindToSend == NULL))
break;

// Copy file information onto a stack based variable as _dos_findnext
// does not like global memory based variable

_fmemcpy ( (LPVOID) &findFileInfo, &(pFindNext->FileInfo), sizeof (FINDT));

bRc = (BYTE) _dos_findnext ( &findFileInfo );

if (bRc)
{
// Send back made up information
pFindToSend->size = -1;
}
else
{
// Copy result back into global memory
_fmemcpy ( pFindToSend, (LPVOID) &findFileInfo , sizeof (FINDT));
}

bRc = Send ( hwndMain, // handle to send message to
(LPSTR) pFindToSend, // Data to Send
sizeof(FINDT), // Data buffer size
bLsnS, // Local Session Number
BW_S_SEND_BACK, // Message sent upon completion
&enumSSendStatus // A signal.
);

NcbFree ( (LPVOID) pFindToSend); // Release Buffer

if (bRc==NO_ERROR)
break;
else
{
MessageBox ( GetActiveWindow(),
"Error in Sending Data",
"Dos_Find_Next",
MB_OK);
break;
}

default:
// Don't know what the command is
sprintf(szErrorBuffer,
"Error unknown command [%d]",
pacPtr->bCommand
);
MessageBox(hwndMain, (LPSTR)szErrorBuffer,"Error", MB_OK);
}


// Free up the Receive Packet
NcbFree ( (LPVOID) pncbNCB);
// Free up the old buffer
NcbFree ( (LPVOID) lpServerData);
fNcbFreed = TRUE;

ServerState = S_CONNECTED;
// All Done. Hang out a RECEIVE
if ((bRc = PostAReceive ( hwndMain)) == NRC_PENDING )
{
ServerState = S_RECEIVING;
return;
}
else
{
/*
* Go back to LISTENing
*/
if ((bRc = PostAListen( hwndMain)) == NRC_PENDING)
{
ServerState = S_LISTENING;
return;
}

}
}

// We should never come here. Show error for debugging purposes

sprintf(szErrorBuffer,
"Error [%d] in ReceiveComplete\n Aborting \n Close Program",
pncbNCB->ncb_cmd_cplt
);
MessageBox(hwndMain, (LPSTR)szErrorBuffer,"Error", MB_OK);

if ( fNcbFreed != TRUE)
{
// Free the NCB
NcbFree ( (LPVOID) pncbNCB);
// Free up the old buffer
NcbFree ( (LPVOID) lpServerData);
}
return;
}

/****************************************************************************

FUNCTION: PostAListen

PURPOSE: The function simply posts a Listen command. It
saves a pointer to posted NCB in a global variable.


****************************************************************************/
BYTE PostAListen ( HWND hwnd )
{
BYTE bRc;
char chRemoteName[ NETBIOS_NAME_LENGTH + 1];

// Listen to anyone
CopyName ( chRemoteName, "*");

if ((bRc = Listen(hwnd,
chServerName,
chRemoteName, /* Listen to anybody */
RECEIVE_NCB_RTO, /* Recv time out value*/
SEND_NCB_STO, /* Send time out value*/
&pncbListenNCB /* Posted Listen NCB */
)) != NRC_PENDING)
{
sprintf(szErrorBuffer,
"Error posting a Listen Server [%s] Error [%x]",
chServerName,
bRc
);
MessageBox(hwnd, (LPSTR)szErrorBuffer,"Error", MB_OK);
return bRc;
}
return (bRc);

}
/****************************************************************************

FUNCTION: PostAReceive

PURPOSE: The function simply posts a Receive command. The routine
saves the pointer to data buffer allocated by Receive
routine in a global variable.

****************************************************************************/

BYTE PostAReceive ( HWND hwnd)
{
BYTE bRc;
if ((bRc = Receive ( hwnd, // Handle to send message to
&lpServerData,// Pointer to Received buffer
SERVER_RECEIVE_SIZE, // Size of Receive buffer
bLsnS, // Local Session Number
TRUE // It is a Server
)) != NRC_PENDING)
{
sprintf(szErrorBuffer,
"Error posting a Receive Server %s Error [%x]",
chServerName,
bRc
);
MessageBox(hwnd, (LPSTR)szErrorBuffer, "Error", MB_OK);
return bRc;
}
return (bRc);
}


  3 Responses to “Category : Files from Magazines
Archive   : MSJV7_4.ZIP
Filename : SERVER.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/