Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1143 lines
33 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
xport.c
Abstract:
This module contains the code for the named pipe transport layer
which explicitly deals with the machanics of doing named pipes.
Author:
Jim Schaad (jimsch) 11-June-93
Wesley Witt (wesw) 25-Nov-93
Environment:
Win32 User
--*/
#ifdef WIN32
#include <windows.h>
#endif
#include <stdlib.h>
#include <defs.h>
#include <string.h>
#include <memory.h>
#include "mm.h"
#include "ll.h"
#include "od.h"
#include "tl.h"
#include "llhpt.h"
#include "mhhpt.h"
#include "lbhpt.h"
#include "emdm.h"
#include "xport.h"
#include "dbgver.h"
#if DBG
DWORD FExpectingReply = 0;
DWORD FExpectingSeq = 0;
CRITICAL_SECTION csExpecting;
#endif
extern AVS Avs;
#ifdef WIN32
LPDMINIT LpDmInit;
LPDMFUNC LpDmFunc;
LPDMDLLINIT LpDmDllInit;
LPUISERVERCB LpUiServer;
void EXPENTRY DMInit (DMTLFUNCTYPE, LPV);
#else
void EXPENTRY DMInit (DMTLFUNCTYPE);
#endif
LPDBF lpdbf = (LPDBF)0; // the debugger helper functions LOCAL
TLCALLBACKTYPE TLCallBack; // central osdebug callback function
//
// these variables are static to prevent collisions with other TL's
//
BOOL FConnected = FALSE;
static LPB lpbDM;
static WORD ibMaxDM;
static WORD ibDM;
static HPID hpidRoot;
LPSTR SzParams;
LPSTR LpszDm;
HANDLE HDm = NULL;
static DWORD pkSeq;
extern CHAR ClientId[];
static char Rgb[MAX_INTERNAL_PACKET + sizeof(NLBLK) + sizeof(MPACKET)];
#define Pnlblk ((PNLBLK) Rgb)
#define PnlblkDm ((PNLBLK) Rgb)
static char RgbReply[MAX_INTERNAL_PACKET + sizeof(NLBLK) + sizeof(MPACKET)];
#define PnlblkRp ((PNLBLK) RgbReply)
static char RgbRequest[MAX_INTERNAL_PACKET + sizeof(NLBLK) + sizeof(MPACKET)];
#define PnlblkRq ((PNLBLK) RgbRequest)
XOSD
SendData(
LPV lpvOut,
int cbOut
);
XOSD
SendRequest(
int mtypeResponse,
LPV lpvOut,
int cbOut,
LPV lpvReply,
int * pcbReply,
DWORD dwTimeOut
);
XOSD EXPENTRY
DMTLFunc(
TLF wCommand,
HPID hpid,
DWORD wParam,
LONG lParam
);
XOSD EXPENTRY
TLFunc(
TLF wCommand,
HPID hpid,
DWORD wParam,
LONG lParam
);
extern BOOL FDMSide;
BOOL
DllVersionMatch(
HANDLE hMod,
LPSTR pType
)
{
DBGVERSIONPROC pVerProc;
LPAVS pavs;
pVerProc = (DBGVERSIONPROC)GetProcAddress(hMod, DBGVERSIONPROCNAME);
if (!pVerProc) {
return(FALSE); // no version entry point
} else {
pavs = (*pVerProc)();
if ((pType[0] != pavs->rgchType[0] || pType[1] != pavs->rgchType[1]) ||
(Avs.rlvt != pavs->rlvt) || (Avs.iRmj != pavs->iRmj)) {
return(FALSE);
}
}
return(TRUE);
}
XOSD EXPENTRY
TLFunc(
TLF wCommand,
HPID hpid,
DWORD wParam,
LONG lParam
)
/*++
Routine Description:
This function contains the dispatch loop for commands comming into
the transport layer. The address of this procedure is exported to
users of the DLL.
Arguments:
wCommand - Supplies the command to be executed.
hpid - Supplies the hpid for which the command is to be executed.
wParam - Supplies information about the command.
lParam - Supplies information about the command.
Return Value:
XOSD error code. xosdNone means that no errors occured. Other
error codes are defined in osdebug\include\od.h.
--*/
{
LPGIS lpgis;
int cb;
LPSTR p;
MPACKET * pMpckt;
XOSD xosd = xosdNone;
LPDBB lpdbb;
AVS dmavs;
switch ( wCommand ) {
case tlfGlobalInit:
DEBUG_OUT("TlFunc: tlfGlobalInit\n");
TLCallBack = (TLCALLBACKTYPE) lParam;
break;
case tlfGlobalDestroy:
DEBUG_OUT("TlFunc: tlfGlobalDestroy\n");
break;
case tlfRegisterDBF:
DEBUG_OUT("TlFunc: tlfRegisterDBF\n");
lpdbf = (LPDBF) lParam;
break;
case tlfInit:
DEBUG_OUT("TlFunc: tlfInit\n");
p = (LPSTR)lParam;
if (strncmp(p, "DMSide", 6) == 0) {
FDMSide = TRUE;
p = strtok(p, " ");
p = strtok(NULL, " ");
SzParams = _strdup( p );
p += (strlen( p ) + 1);
if (LpDmInit != NULL) {
xosd = LpDmInit(DMTLFunc, (LPV)lParam);
} else {
xosd = xosdUnknown;
}
} else {
SzParams = _strdup( p );
}
break;
case tlfDestroy:
DEBUG_OUT("TlFunc: tlfDestroy\n");
if (LpDmInit != NULL) {
LpDmInit(NULL, NULL);
}
if (HDm != NULL) {
FreeLibrary(HDm);
HDm = NULL;
LpDmInit = NULL;
LpDmFunc = NULL;
}
if (LpUiServer) {
DEBUG_OUT(("NL: tlcbDisconnect\n"));
LpUiServer(tlcbDisconnect, 0, 0, 0, 0);
}
TlDestroyTransport();
FConnected = FALSE;
DEBUG_OUT(("NL: tlfDestroy exit\n"));
break;
case tlfSetUIStruct: // not used for local case
DEBUG_OUT("TlFunc: tlfSetUIStruct\n");
break;
case tlfGetProc:
DEBUG_OUT("TlFunc: tlfGetProc\n");
*((TLFUNCTYPE FAR *) lParam) = TLFunc;
break;
case tlfConnect:
DEBUG_OUT("TlFunc: tlfConnect\n");
if (hpid) {
hpidRoot = hpid;
} else {
if (lParam) {
if ((xosd = TlConnectTransport()) == xosdNone) {
FConnected = TRUE;
strncpy( (LPSTR)lParam, ClientId, wParam );
}
} else {
if (TlCreateClient(SzParams) != xosdNone) {
xosd = xosdCannotConnect;
} else {
FConnected = TRUE;
}
}
}
break;
case tlfDisconnect:
DEBUG_OUT("TlFunc: tlfDisconnect\n");
TlDestroyTransport();
FConnected = FALSE;
break;
case tlfRemoteQuit:
DEBUG_OUT("TlFunc: tlfRemoteQuit\n");
//
// tell the dm that it is disconnected from the debugger
//
lpdbb = (LPDBB)Rgb;
lpdbb->dmf = dmfRemoteQuit;
lpdbb->hpid = 0;
lpdbb->htid = 0;
LpDmFunc(sizeof(*lpdbb), (char *) lpdbb);
TlDestroyTransport();
break;
case tlfSetBuffer:
DEBUG_OUT("TlFunc: tlfSetBuffer\n");
lpbDM = (LPB) lParam;
ibMaxDM = (short)wParam;
break;
case tlfDebugPacket:
DEBUG_OUT("TlFunc: tlfDebugPacket\n");
if (FConnected) {
if (wParam > MAX_INTERNAL_PACKET) {
pMpckt = (MPACKET * ) Pnlblk->rgchData;
Pnlblk->mtypeBlk = mtypeAsyncMulti;
Pnlblk->hpid = hpid;
Pnlblk->cchMessage = MAX_INTERNAL_PACKET + sizeof(MPACKET);
Pnlblk->seq = ++pkSeq;
pMpckt->packetNum = 0;
pMpckt->packetCount = (((short)wParam + MAX_INTERNAL_PACKET - 1) /
MAX_INTERNAL_PACKET);
while (wParam > MAX_INTERNAL_PACKET) {
memcpy(pMpckt->rgchData, (LPB) lParam, MAX_INTERNAL_PACKET);
xosd = SendData(Pnlblk, sizeof(NLBLK) + sizeof(MPACKET) +
MAX_INTERNAL_PACKET);
if (xosd != xosdNone) {
return xosdUnknown;
}
wParam -= MAX_INTERNAL_PACKET;
lParam += MAX_INTERNAL_PACKET;
pMpckt->packetNum += 1;
}
memcpy(pMpckt->rgchData, (LPB) lParam, wParam);
Pnlblk->cchMessage = (short)(wParam + sizeof(MPACKET));
xosd = SendData(Pnlblk, sizeof(NLBLK) + sizeof(MPACKET) + wParam);
} else {
Pnlblk->mtypeBlk = mtypeAsync;
Pnlblk->hpid = hpid;
Pnlblk->cchMessage = (short)wParam;
Pnlblk->seq = ++pkSeq;
memcpy(Pnlblk->rgchData, (LPB) lParam, wParam);
xosd = SendData(Pnlblk, sizeof(NLBLK) + wParam);
}
} else {
xosd = xosdLineNotConnected;
}
break;
case tlfReply:
DEBUG_OUT("TlFunc: tlfReply\n");
#if DBG
EnterCriticalSection(&csExpecting);
assert(FExpectingReply);
FExpectingReply = 0;
LeaveCriticalSection(&csExpecting);
#endif
if (FConnected) {
if (wParam > MAX_INTERNAL_PACKET) {
pMpckt = (MPACKET * ) PnlblkRp->rgchData;
PnlblkRp->mtypeBlk = mtypeReplyMulti;
PnlblkRp->hpid = hpid;
PnlblkRp->cchMessage = MAX_INTERNAL_PACKET + sizeof(MPACKET);
PnlblkRp->seq = ++pkSeq;
pMpckt->packetNum = 0;
pMpckt->packetCount = (((short)wParam + MAX_INTERNAL_PACKET - 1) /
MAX_INTERNAL_PACKET);
while (wParam > MAX_INTERNAL_PACKET) {
memcpy(pMpckt->rgchData, (LPB) lParam, MAX_INTERNAL_PACKET);
xosd = SendData(PnlblkRp, sizeof(NLBLK) + sizeof(MPACKET) +
MAX_INTERNAL_PACKET);
if (xosd != xosdNone) {
return xosdUnknown;
}
wParam -= MAX_INTERNAL_PACKET;
lParam += MAX_INTERNAL_PACKET;
pMpckt->packetNum += 1;
}
memcpy(pMpckt->rgchData, (LPB) lParam, wParam);
PnlblkRp->cchMessage = (short)(wParam + sizeof(MPACKET));
xosd = SendData(PnlblkRp, sizeof(NLBLK) + sizeof(MPACKET) + wParam);
} else {
PnlblkRp->mtypeBlk = mtypeReply;
PnlblkRp->hpid = hpid;
PnlblkRp->cchMessage = (short)wParam;
PnlblkRp->seq = ++pkSeq;
memcpy(PnlblkRp->rgchData, (LPB) lParam, wParam);
xosd = SendData(PnlblkRp, sizeof(NLBLK) + wParam);
}
} else {
xosd = xosdLineNotConnected;
}
break;
case tlfRequest:
DEBUG_OUT("TlFunc: tlfRequest\n");
if ( !FConnected ) {
xosd = xosdLineNotConnected;
} else {
cb = ibMaxDM;
if (wParam > MAX_INTERNAL_PACKET) {
pMpckt = (MPACKET * ) PnlblkRq->rgchData;
PnlblkRq->mtypeBlk = mtypeSyncMulti;
PnlblkRq->hpid = hpid;
PnlblkRq->cchMessage = MAX_INTERNAL_PACKET + sizeof(MPACKET);
PnlblkRq->seq = ++pkSeq;
pMpckt->packetNum = 0;
pMpckt->packetCount = (((short)wParam + MAX_INTERNAL_PACKET - 1) /
MAX_INTERNAL_PACKET);
while (wParam > MAX_INTERNAL_PACKET) {
memcpy(pMpckt->rgchData, (LPB) lParam, MAX_INTERNAL_PACKET);
xosd = SendData(PnlblkRq, sizeof(NLBLK) + sizeof(MPACKET) +
MAX_INTERNAL_PACKET);
if (xosd != xosdNone) {
return xosdUnknown;
}
wParam -= MAX_INTERNAL_PACKET;
lParam += MAX_INTERNAL_PACKET;
pMpckt->packetNum += 1;
}
PnlblkRq->cchMessage = (short)(wParam + sizeof(MPACKET));
memcpy(pMpckt->rgchData, (LPB) lParam, wParam);
xosd = SendRequest(mtypeReply, PnlblkRq, sizeof(NLBLK) + sizeof(MPACKET) +
wParam, lpbDM, &cb, INFINITE);
} else {
PnlblkRq->mtypeBlk = mtypeSync;
PnlblkRq->cchMessage = (short)wParam;
PnlblkRq->hpid = hpid;
PnlblkRq->seq = ++pkSeq;
memcpy(PnlblkRq->rgchData, (char *) lParam, wParam);
xosd = SendRequest(mtypeReply, PnlblkRq, wParam + sizeof(NLBLK), lpbDM, &cb, INFINITE);
}
}
break;
case tlfGetVersion:
DEBUG_OUT("TlFunc: tlfGetVersion\n");
{
int cb = wParam;
//
// Get the version information from the remote side. If it doesn't
// return anything in 10 seconds, time out and return 0's.
//
// lParam = buffer to fill in
// wParam = size of buffer
//
// sets globals lpchVersionReply = lParam
// cchVersionReplyMax = wParam
//
//
DEBUG_OUT("NL: tlfGetVersion\n");
if (!FConnected) {
DEBUG_OUT(("NL: tlfGetVersion not on line\n"));
xosd = xosdLineNotConnected;
break;
}
//
// must be connected
// basically works like a tlfRequest with a timeout and a
// target in the transport rather than the DM/EM.
//
//
// Create the desired packet. The packet consists of:
// type = mtypeVersionRequest
// length = 0
// hpid = current pid
//
Pnlblk->mtypeBlk = mtypeVersionRequest;
Pnlblk->cchMessage = 0;
Pnlblk->hpid = hpid;
Pnlblk->seq = ++pkSeq;
//
// send the version request packet
//
xosd = SendRequest(mtypeVersionReply, Pnlblk,
sizeof(NLBLK), (void *) lParam, &cb, 5);
if (xosd == xosdNone) {
} else {
memset((LPCH) lParam, 0, wParam);
}
DEBUG_OUT("NL: tlfVersionCheck exit\n");
}
break;
case tlfSendVersion:
DEBUG_OUT("TlFunc: tlfSendVersion\n");
if (!FConnected) {
return xosdLineNotConnected;
} else {
// Send the version information to
// the other side. This is in response to a mtypeVersionRequest
// (tlfGetVersion)
// Create a packet with the appropriate data packet
// type = mtypeVersionReply cb = sizeof(Avs);
// hpid = hpid
// data = Version structure
if (HDm) {
DBGVERSIONPROC verproc =
(DBGVERSIONPROC)GetProcAddress(HDm, DBGVERSIONPROCNAME);
dmavs = *verproc();
} else {
dmavs = Avs;
}
Pnlblk->mtypeBlk = mtypeVersionReply;
Pnlblk->hpid = hpid;
Pnlblk->cchMessage = sizeof(AVS);
Pnlblk->seq = ++pkSeq;
memcpy(&Pnlblk->rgchData,(LPCH)&dmavs, sizeof(AVS));
SendData(Pnlblk, sizeof(NLBLK) + sizeof(AVS));
DEBUG_OUT(("Send Reply to version request packet\n"));
}
break;
case tlfGetInfo:
DEBUG_OUT("TlFunc: tlfGetInfo\n");
lpgis = (LPGIS) lParam;
_fstrcpy(lpgis->rgchInfo, "Local Transport Layer (LOCAL:)");
lpgis->fCanSetup = FALSE;
break;
case tlfSetup:
DEBUG_OUT("TlFunc: tlfSetup\n");
break;
case tlfLoadDM:
DEBUG_OUT("TlFunc: tlfLoadDM\n");
if (lParam) {
LpszDm = (char *) lParam;
} else {
LpszDm = "DM.DLL";
}
HDm = LoadLibrary(LpszDm);
if (HDm == NULL) {
xosd = xosdUnknown;
break;
}
// Do DM dll version check here
if (! DllVersionMatch(HDm, "DM")) {
xosd = xosdBadVersion;
FreeLibrary(HDm);
break;
}
if ((LpDmInit = (LPDMINIT) GetProcAddress(HDm, "DMInit")) == NULL) {
xosd = xosdUnknown;
FreeLibrary(HDm);
break;
}
if ((LpDmFunc = (LPDMFUNC) GetProcAddress(HDm, "DMFunc")) == NULL) {
xosd = xosdUnknown;
FreeLibrary(HDm);
LpDmInit = NULL;
break;
}
if ((LpDmDllInit = (LPDMDLLINIT) GetProcAddress(HDm, "DmDllInit")) ==
NULL) {
xosd = xosdUnknown;
FreeLibrary(HDm);
LpDmFunc = NULL;
LpDmInit = NULL;
break;
}
#ifdef WIN32
if (LpDmDllInit(lpdbf) == FALSE) {
xosd = xosdUnknown;
FreeLibrary(HDm);
break;
}
#endif
break;
case tlfSetErrorCB:
DEBUG_OUT("TlFunc: tlfSetErrorCB\n");
LpUiServer = (LPUISERVERCB) lParam;
break;
default:
DEBUG_OUT("TlFunc: **** unknown tlf ****\n");
assert ( FALSE );
break;
}
return xosd;
}
XOSD EXPENTRY
DMTLFunc(
TLF wCommand,
HPID hpid,
DWORD wParam,
LONG lParam
)
{
XOSD xosd = xosdNone;
int cb;
MPACKET * pMpckt;
switch ( wCommand ) {
case tlfInit:
DEBUG_OUT( "DMTlFunc: tlfInit\n" );
break;
case tlfDestroy:
DEBUG_OUT( "DMTlFunc: tlfDestroy\n" );
break;
case tlfConnect:
DEBUG_OUT( "DMTlFunc: tlfConnect\n" );
if (TlCreateTransport(SzParams) != xosdNone) {
xosd = xosdCannotConnect;
}
break;
case tlfDisconnect:
DEBUG_OUT( "DMTlFunc: tlfDisconnect\n" );
TlDestroyTransport();
FConnected = FALSE;
break;
case tlfSetBuffer: lpbDM = (LPB) lParam;
DEBUG_OUT( "DMTlFunc: tlfSetBuffer\n" );
ibMaxDM = (short)wParam;
break;
case tlfDebugPacket:
DEBUG_OUT( "DMTlFunc: tlfDebugPacket\n" );
if (FConnected) {
if (wParam > MAX_INTERNAL_PACKET) {
pMpckt = (MPACKET * ) PnlblkDm->rgchData;
PnlblkDm->mtypeBlk = mtypeAsyncMulti;
PnlblkDm->hpid = hpid;
PnlblkDm->cchMessage = MAX_INTERNAL_PACKET + sizeof(MPACKET);
PnlblkDm->seq = ++pkSeq;
pMpckt->packetNum = 0;
pMpckt->packetCount = (((short)wParam + MAX_INTERNAL_PACKET - 1) /
MAX_INTERNAL_PACKET);
while (wParam > MAX_INTERNAL_PACKET) {
memcpy(pMpckt->rgchData, (LPB) lParam, MAX_INTERNAL_PACKET);
xosd = SendData(PnlblkDm, sizeof(NLBLK) + sizeof(MPACKET) +
MAX_INTERNAL_PACKET);
if (xosd != xosdNone) {
return xosdUnknown;
}
wParam -= MAX_INTERNAL_PACKET;
lParam += MAX_INTERNAL_PACKET;
pMpckt->packetNum += 1;
}
memcpy(pMpckt->rgchData, (LPB) lParam, wParam);
PnlblkDm->cchMessage = (short)(wParam + sizeof(MPACKET));
xosd = SendData(PnlblkDm, sizeof(NLBLK) + sizeof(MPACKET) + wParam);
} else {
PnlblkDm->mtypeBlk = mtypeAsync;
PnlblkDm->hpid = hpid;
PnlblkDm->cchMessage = (short)wParam;
PnlblkDm->seq = ++pkSeq;
memcpy(PnlblkDm->rgchData, (LPB) lParam, wParam);
xosd = SendData(PnlblkDm, sizeof(NLBLK) + wParam);
}
} else {
xosd = xosdIDError;
}
break;
case tlfReply:
DEBUG_OUT( "DMTlFunc: tlfReply\n" );
#if DBG
EnterCriticalSection(&csExpecting);
assert(FExpectingReply);
FExpectingReply = 0;
LeaveCriticalSection(&csExpecting);
#endif
if (FConnected) {
if (wParam > MAX_INTERNAL_PACKET) {
pMpckt = (MPACKET * ) PnlblkRp->rgchData;
PnlblkRp->mtypeBlk = mtypeReplyMulti;
PnlblkRp->hpid = hpid;
PnlblkRp->cchMessage = MAX_INTERNAL_PACKET + sizeof(MPACKET);
PnlblkRp->seq = ++pkSeq;
pMpckt->packetNum = 0;
pMpckt->packetCount = (((short)wParam + MAX_INTERNAL_PACKET - 1) /
MAX_INTERNAL_PACKET);
while (wParam > MAX_INTERNAL_PACKET) {
memcpy(pMpckt->rgchData, (LPB) lParam, MAX_INTERNAL_PACKET);
xosd = SendData(PnlblkRp, sizeof(NLBLK) + sizeof(MPACKET) +
MAX_INTERNAL_PACKET);
if (xosd != xosdNone) {
return xosdUnknown;
}
wParam -= MAX_INTERNAL_PACKET;
lParam += MAX_INTERNAL_PACKET;
pMpckt->packetNum += 1;
}
memcpy(pMpckt->rgchData, (LPB) lParam, wParam);
PnlblkRp->cchMessage = (short)(wParam + sizeof(MPACKET));
xosd = SendData(PnlblkRp, sizeof(NLBLK) + sizeof(MPACKET) + wParam);
} else {
PnlblkRp->mtypeBlk = mtypeReply;
PnlblkRp->hpid = hpid;
PnlblkRp->cchMessage = (short)wParam;
PnlblkRp->seq = ++pkSeq;
memcpy(PnlblkRp->rgchData, (LPB) lParam, wParam);
xosd = SendData(PnlblkRp, sizeof(NLBLK) + wParam);
}
} else {
xosd = xosdIDError;
}
break;
case tlfRequest:
DEBUG_OUT( "DMTlFunc: tlfRequest\n" );
if ( !FConnected ) {
xosd = xosdIDError;
} else {
cb = ibMaxDM;
if (wParam > MAX_INTERNAL_PACKET) {
pMpckt = (MPACKET * ) PnlblkRq->rgchData;
PnlblkRq->mtypeBlk = mtypeSyncMulti;
PnlblkRq->hpid = hpid;
PnlblkRq->cchMessage = MAX_INTERNAL_PACKET + sizeof(MPACKET);
PnlblkRq->seq = ++pkSeq;
pMpckt->packetNum = 0;
pMpckt->packetCount = (((short)wParam + MAX_INTERNAL_PACKET - 1) /
MAX_INTERNAL_PACKET);
while (wParam > MAX_INTERNAL_PACKET) {
memcpy(pMpckt->rgchData, (LPB) lParam, MAX_INTERNAL_PACKET);
xosd = SendData(PnlblkRq, sizeof(NLBLK) + sizeof(MPACKET) +
MAX_INTERNAL_PACKET);
if (xosd != xosdNone) {
return xosdUnknown;
}
wParam -= MAX_INTERNAL_PACKET;
lParam += MAX_INTERNAL_PACKET;
pMpckt->packetNum += 1;
}
PnlblkRq->cchMessage = (short)(wParam + sizeof(MPACKET));
memcpy(pMpckt->rgchData, (LPB) lParam, wParam);
xosd = SendRequest(mtypeReply, PnlblkRq, sizeof(NLBLK) +
sizeof(MPACKET) +
wParam, lpbDM, &cb, INFINITE);
} else {
PnlblkRq->mtypeBlk = mtypeSync;
PnlblkRq->cchMessage = (short)wParam;
PnlblkRq->hpid = hpid;
PnlblkRq->seq = ++pkSeq;
memcpy(PnlblkRq->rgchData, (char *) lParam, wParam);
xosd = SendRequest(mtypeReply, PnlblkRq, wParam + sizeof(NLBLK),
lpbDM, &cb, INFINITE);
}
}
break;
default:
DEBUG_OUT( "DMTlFunc: **** unknown tlf ****\n" );
assert ( FALSE );
break;
}
return xosd;
}
BOOL
CallBack(
PNLBLK pnlblk,
int cb
)
{
MPACKET * pMpacket;
DPACKET * pDpckt;
static int cbMulti = 0;
static char * pbMulti = NULL;
switch( pnlblk->mtypeBlk ) {
case mtypeVersionRequest:
DEBUG_OUT("CallBack: mtypeVersionRequest\n" );
TLFunc(tlfSendVersion, pnlblk->hpid, 0, 0);
break;
case mtypeSyncMulti:
case mtypeAsyncMulti:
#if DBG
if (pnlblk->mtypeBlk == mtypeAsyncMulti) {
DEBUG_OUT("CallBack: mtypeAsyncMulti\n" );
EnterCriticalSection(&csExpecting);
FExpectingReply = 0;
LeaveCriticalSection(&csExpecting);
} else {
DEBUG_OUT("CallBack: mtypeSyncMulti\n" );
EnterCriticalSection(&csExpecting);
FExpectingReply = 1;
FExpectingSeq = pnlblk->seq;
LeaveCriticalSection(&csExpecting);
}
#endif
assert( cb == (int) (pnlblk->cchMessage + sizeof(NLBLK)) );
if (FConnected) {
pMpacket = (MPACKET *) pnlblk->rgchData;
if (pMpacket->packetNum == 0) {
if (cbMulti < pMpacket->packetCount * MAX_INTERNAL_PACKET) {
pbMulti = realloc(pbMulti, pMpacket->packetCount *
MAX_INTERNAL_PACKET);
}
}
memcpy(pbMulti + pMpacket->packetNum * MAX_INTERNAL_PACKET,
pMpacket->rgchData, pnlblk->cchMessage - sizeof(MPACKET));
if (pMpacket->packetNum + 1 == pMpacket->packetCount) {
cb = pMpacket->packetNum * MAX_INTERNAL_PACKET +
pnlblk->cchMessage - sizeof(MPACKET);
if (TLCallBack != NULL) {
TLCallBack( pnlblk->hpid, (WORD) cb, (LONG) pbMulti);
} else if (LpDmFunc != NULL) {
LpDmFunc((WORD) cb, pbMulti);
}
}
}
break;
case mtypeAsync:
case mtypeSync:
#if DBG
if (pnlblk->mtypeBlk == mtypeAsync) {
DEBUG_OUT("CallBack: mtypeAsync\n" );
EnterCriticalSection(&csExpecting);
FExpectingReply = 0;
LeaveCriticalSection(&csExpecting);
} else {
DEBUG_OUT("CallBack: mtypeSync\n" );
EnterCriticalSection(&csExpecting);
FExpectingReply = 1;
FExpectingSeq = pnlblk->seq;
LeaveCriticalSection(&csExpecting);
}
#endif
assert( cb == (int) (pnlblk->cchMessage + sizeof(NLBLK)) );
if (FConnected) {
if (TLCallBack != NULL) {
TLCallBack( pnlblk->hpid, pnlblk->cchMessage,
(LONG) pnlblk->rgchData);
} else if (LpDmFunc != NULL) {
LpDmFunc(pnlblk->cchMessage, pnlblk->rgchData);
}
}
break;
case mtypeDisconnect:
DEBUG_OUT("CallBack: mtypeDisconnect\n" );
if (TLCallBack != NULL) {
RTP rtp = { dbcRemoteQuit, pnlblk->hpid, 0, 0 };
TLCallBack(pnlblk->hpid, sizeof(rtp), (LONG)&rtp);
}
if (LpUiServer) {
pDpckt = (DPACKET *) pnlblk->rgchData;
LpUiServer( tlcbDisconnect,
pDpckt->hpid,
pDpckt->htid,
pDpckt->fContinue,
0
);
}
break;
case mtypeTransportIsDead:
DEBUG_OUT("CallBack: mtypeTransportIsDead\n" );
TransportFailure();
return FALSE;
break;
default:
assert(FALSE);
}
return TRUE;
}
VOID
TransportFailure(
VOID
)
{
DEBUG_OUT("*** TransportFailure()\n" );
if (LpUiServer) {
LpUiServer(tlcbDisconnect, 0, 0, 0, 0);
TLFunc( tlfRemoteQuit, 0, 0, 0 );
} else if (TLCallBack) {
RTP rtp = { dbcRemoteQuit, hpidRoot, 0, 0 };
TLCallBack( hpidRoot, sizeof(rtp), (LONG)&rtp );
}
FConnected = FALSE;
return;
}
XOSD
SendData(
LPV lpvOut,
int cbOut
)
{
if (!TlWriteTransport(lpvOut, cbOut)) {
return xosdWrite;
}
return xosdNone;
}
//
// data structures for tlfreplys
//
// these structures exist in the physical layer of the
// transport layer (pipe, serial, ...)
//
extern CRITICAL_SECTION CsReplys;
extern int IReplys;
extern REPLY RgReplys[];
XOSD
SendRequest(
int mtypeResponse,
LPV lpvOut,
int cbOut,
LPV lpvReply,
int * pcbReply,
DWORD dwTimeOut
)
/*++
Routine Description:
description-of-function.
Arguments:
mtypeResponse - Supplies the packet type to be used as a response
lpvOut - Supplies the request packet
cbOut - Supplies length of request packet
lpvIn - Returns the reply data
cbIn - Supplies length of return bugger
dwTimeOut - Supplies -1 or # of seconds to wait before timeout
Return Value:
XOSD error code
--*/
{
int i;
XOSD xosd = xosdNone;
//
// Allow us to work with impunity
//
EnterCriticalSection(&CsReplys);
//
// Are we in trouble due to overflow?
//
if (IReplys == SIZE_OF_REPLYS) {
LeaveCriticalSection(&CsReplys);
return xosdUnknown;
}
assert( IReplys == 0 );
//
// Setup the reply location
//
RgReplys[IReplys].lpb = (char *) lpvReply;
RgReplys[IReplys].cbBuffer = *pcbReply;
RgReplys[IReplys].cbRet = 0;
i = IReplys;
IReplys += 1;
//
//
//
ResetEvent( RgReplys[i].hEvent );
LeaveCriticalSection(&CsReplys);
//
// No finally mail the request out
//
if (!TlWriteTransport(lpvOut, cbOut)) {
EnterCriticalSection(&CsReplys);
IReplys -= 1;
LeaveCriticalSection(&CsReplys);
return xosdWrite;
}
//
// Wait for the reply to come back
//
if (dwTimeOut != INFINITE) {
dwTimeOut *= 1000;
}
WaitForSingleObject(RgReplys[i].hEvent, dwTimeOut);
//
// Now get the message back
//
EnterCriticalSection(&CsReplys);
RgReplys[i].lpb = NULL;
*pcbReply = RgReplys[i].cbRet;
if (RgReplys[i].cbRet == 0) {
xosd = xosdUnknown;
}
assert( IReplys == i + 1 );
if (IReplys == i + 1) {
IReplys = i;
} else {
xosd = xosdUnknown;
}
LeaveCriticalSection(&CsReplys);
return xosd;
}
VOID
DebugPrint(
LPSTR szFormat,
...
)
{
va_list marker;
int n;
char rgchDebug[4096];
va_start( marker, szFormat );
n = _vsnprintf(rgchDebug, sizeof(rgchDebug), szFormat, marker );
va_end( marker);
if (n == -1) {
rgchDebug[sizeof(rgchDebug)-1] = '\0';
}
OutputDebugString( rgchDebug );
return;
}
VOID
ShowAssert(
LPSTR condition,
UINT line,
LPSTR file
)
{
char text[4096];
int id;
_snprintf(text, sizeof(text), "Assertion failed - Line:%u, File:%Fs, Condition:%Fs", line, file, condition);
DebugPrint( "%s\r\n", text );
id = MessageBox( NULL, text, "Pipe Transport", MB_YESNO | MB_ICONHAND | MB_TASKMODAL | MB_SETFOREGROUND );
if (id != IDYES) {
DebugBreak();
}
return;
}