1316 lines
46 KiB
C
1316 lines
46 KiB
C
/*
|
|
universal multiplayer library level 0 implementation file
|
|
transport layer: Shared memory PC-windows 95
|
|
*/
|
|
|
|
#include "warnings.h"
|
|
|
|
#include "Privl0ShaMem.h"
|
|
#include "L0GlDef.h"
|
|
#include "PrivNetDef.h"
|
|
#include "NetMemCo.h"
|
|
#include "NetEnd.h"
|
|
|
|
/*
|
|
Definition of data :
|
|
*/
|
|
|
|
#define C_ucMaxNameSize ((unsigned char)50)
|
|
#define C_uwL0MaxNumberOfSharedMemChannels ((tduwNetChannel)15)
|
|
|
|
/* Handle and pointer to the reading shared memory */
|
|
static HANDLE gs_hOwnSharedMem;
|
|
static void *gs_pvOwnSharedMem;
|
|
static unsigned long gs_ulOwnMemoryLength;
|
|
static char *gs_pcOwnSharedMemName;
|
|
static unsigned char gs_ucOwnSharedMemNameLength;
|
|
static char *gs_pcOwnSharedMemMutexName;
|
|
|
|
/* Array of channel :*/
|
|
tdstL0PCWin95SharedMemChannel gs_a_stL0PCWin95SharedMemChannels[C_uwL0MaxNumberOfSharedMemChannels];
|
|
|
|
static char gs_bL0PCWin95SharedMemInitState;
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : uwL0PCWin95SharedMemGetSlot
|
|
Search for a channel corresponding to the name given in parameters
|
|
If such a channel is not found , the functions retrieves a free slot
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
The name of a shared memory and its length
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
A channel or C_ulInvalidChannel if no one is found
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 24, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
tduwNetChannel uwL0PCWin95SharedMemGetSlot(unsigned char ucRemoteSharedMemNameSize,char *pcRemoteSharedMemName)
|
|
{
|
|
tduwNetChannel c_uwCount;
|
|
tduwNetChannel uwFreeSlot;
|
|
uwFreeSlot = C_uwNetInvalidChannel;
|
|
c_uwCount = C_uwL0MaxNumberOfSharedMemChannels;
|
|
while
|
|
(
|
|
(c_uwCount != C_uwNetInvalidChannel)&&
|
|
(
|
|
(gs_a_stL0PCWin95SharedMemChannels[c_uwCount].m_ucRemoteSharedMemNameSize != ucRemoteSharedMemNameSize)||
|
|
(memcmp(gs_a_stL0PCWin95SharedMemChannels[c_uwCount].m_pcRemoteSharedMemName,pcRemoteSharedMemName,ucRemoteSharedMemNameSize)!=0)
|
|
)
|
|
)
|
|
{
|
|
if(!gs_a_stL0PCWin95SharedMemChannels[c_uwCount].m_ubf1IsSlotInUse)
|
|
uwFreeSlot = c_uwCount;
|
|
c_uwCount--;
|
|
}
|
|
return (c_uwCount==C_uwNetInvalidChannel)?uwFreeSlot : c_uwCount;
|
|
}
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : uwL0PCWin95SharedMemStartChannelScan
|
|
Returns the first channel
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
None
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
The first valid channel scanning the array from the end to the begining
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 24, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
tduwNetChannel uwL0PCWin95SharedMemStartChannelScan(void)
|
|
{
|
|
tduwNetChannel c_uwCount;
|
|
c_uwCount = C_uwL0MaxNumberOfSharedMemChannels-1;
|
|
while
|
|
(
|
|
(c_uwCount != C_uwNetInvalidChannel)&&
|
|
(!gs_a_stL0PCWin95SharedMemChannels[c_uwCount].m_ubf1IsSlotInUse)
|
|
)
|
|
c_uwCount--;
|
|
return c_uwCount;
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : uwL0PCWin95SharedMemStartBroadcastChannelScan
|
|
Returns the first broadcast channel
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
None
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
The first broadcast channel, searching from the end of the array to the begining
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 24, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
tduwNetChannel uwL0PCWin95SharedMemStartBroadcastChannelScan(void)
|
|
{
|
|
tduwNetChannel c_uwCount;
|
|
c_uwCount = C_uwL0MaxNumberOfSharedMemChannels-1;
|
|
while
|
|
(
|
|
(c_uwCount != C_uwNetInvalidChannel)&&
|
|
(!gs_a_stL0PCWin95SharedMemChannels[c_uwCount].m_ubf1IsSlotInUse)&&
|
|
(!gs_a_stL0PCWin95SharedMemChannels[c_uwCount].m_ubf1IsSlotBroadcast)
|
|
)
|
|
c_uwCount--;
|
|
return c_uwCount;
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : uwL0PCWin95SharedMemNextChannel
|
|
Returns the next channel
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
A channel
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
Search for the next valid channel scanning the array from the channel specified
|
|
in the parameter to the begining
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 24, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
tduwNetChannel uwL0PCWin95SharedMemNextChannel(tduwNetChannel uwChannel)
|
|
{
|
|
tduwNetChannel c_uwCount;
|
|
c_uwCount = (uwChannel != C_uwNetInvalidChannel)?uwChannel-1:C_uwNetInvalidChannel;
|
|
while
|
|
(
|
|
(c_uwCount != C_uwNetInvalidChannel)&&
|
|
(!gs_a_stL0PCWin95SharedMemChannels[c_uwCount].m_ubf1IsSlotInUse)
|
|
)
|
|
c_uwCount--;
|
|
return c_uwCount;
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : uwL0PCWin95SharedMemNextBroadcastChannel
|
|
Returns the next broadcast channel
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
A channel
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
Always the invalid channel
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 21, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
tduwNetChannel uwL0PCWin95SharedMemNextBroadcastChannel(tduwNetChannel uwChannel)
|
|
{
|
|
tduwNetChannel c_uwCount;
|
|
c_uwCount = (uwChannel != C_uwNetInvalidChannel)?uwChannel-1:C_uwNetInvalidChannel;
|
|
while
|
|
(
|
|
(c_uwCount != C_uwNetInvalidChannel)&&
|
|
(!gs_a_stL0PCWin95SharedMemChannels[c_uwCount].m_ubf1IsSlotInUse)&&
|
|
(!gs_a_stL0PCWin95SharedMemChannels[c_uwCount].m_ubf1IsSlotBroadcast)
|
|
)
|
|
c_uwCount--;
|
|
return c_uwCount;
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : eL0PCWin95SharedMemReadData
|
|
Reads a message
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
A channel
|
|
A pointer to the new message
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
An tdeErrorStatus code
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 23, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Comment : a mutex is used to synchronize access to the shared memory
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
NetLib_tdeErrorStatus eL0PCWin95SharedMemReadData(tduwNetChannel*p_uwChannel,tdpPointer*ppMessage)
|
|
{
|
|
HANDLE hOwnMutex;
|
|
unsigned char *p_ucOffset;
|
|
unsigned long ulTotalBytesToShift;
|
|
unsigned long ulBytesToShift;
|
|
unsigned long ulMessageBytes;
|
|
tduwNetChannel uwNewChannel;
|
|
tdstNetMessage *p_stNewMsg;
|
|
|
|
*ppMessage = (tdpPointer)C_pNull;
|
|
|
|
/* Get the mutex to access to the shared memory*/
|
|
hOwnMutex = CreateMutex(NULL,FALSE,gs_pcOwnSharedMemMutexName);
|
|
if(hOwnMutex == (HANDLE)C_pNull)
|
|
return NetLib_E_es_SharedMemMutexFailure;
|
|
/* Wait for the mutex*/
|
|
while(WaitForSingleObject(hOwnMutex,0)!=WAIT_OBJECT_0);
|
|
/* We 'v got the mutex. So access the memory :*/
|
|
/* Go after the header :*/
|
|
p_ucOffset = M_p_ucMsgSharedMemGetFirstL0MsgOffset(gs_pvOwnSharedMem);
|
|
/* Check if there is message in the buffer :*/
|
|
if(*M_p_ucMsgSharedMemGetIsMessageOffset(p_ucOffset) == 0xff)
|
|
{/* There is no message in the buffer*/
|
|
/* Relase the mutex and close the handler*/
|
|
ReleaseMutex(hOwnMutex);
|
|
CloseHandle(hOwnMutex);
|
|
return NetLib_E_es_FIFOIsEmpty;
|
|
}
|
|
/* Else, there is a message in the shared memory*/
|
|
/* Check that it is a valid message :*/
|
|
p_stNewMsg = M_p_stMsgSharedMemGetMessageOffset(p_ucOffset);
|
|
/* if big/little endian differs, swap the header before anything else*/
|
|
if (p_stNewMsg->uxHeadBigEndian!=NetLib_ucGetLittleBigEndian())
|
|
NetLib_eSwapLittleBigEndianMsgHeader(p_stNewMsg);
|
|
|
|
if(
|
|
(
|
|
M_uwCheckSumSlot(p_stNewMsg)!=M_uwProcessCheckSum(p_stNewMsg))||
|
|
(p_stNewMsg->eMessageType >= E_Net_mt_LastSysMsg)||
|
|
(p_stNewMsg->uwMessageSizeInBytes >= gs_ulOwnMemoryLength)
|
|
)
|
|
{
|
|
/* data in shared memory are corrupted*/
|
|
/* so reset it and return an error code */
|
|
memset
|
|
(
|
|
p_ucOffset,
|
|
0xff,
|
|
gs_ulOwnMemoryLength-C_ucSharedMemMsgHeaderSize
|
|
);
|
|
ReleaseMutex(hOwnMutex);
|
|
CloseHandle(hOwnMutex);
|
|
return NetLib_E_es_SharedMemDataCorrupted;
|
|
}
|
|
|
|
ulMessageBytes =
|
|
sizeof(tdstNetMessage) +
|
|
p_stNewMsg->uwMessageSizeInBytes;
|
|
*ppMessage = pMalloc(ulMessageBytes);
|
|
if(*ppMessage == C_pNull)
|
|
{
|
|
/* Relase the mutex and close the handler*/
|
|
ReleaseMutex(hOwnMutex);
|
|
CloseHandle(hOwnMutex);
|
|
return NetLib_E_es_NotEnoughMemory;
|
|
}
|
|
/* Retrieve the message :*/
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
*ppMessage,
|
|
p_stNewMsg,
|
|
ulMessageBytes
|
|
);
|
|
|
|
/* Look for the channel :*/
|
|
uwNewChannel = uwL0PCWin95SharedMemGetSlot
|
|
(
|
|
*M_p_ucMsgSharedMemGetSenderNameLengthOffset(p_ucOffset),/* The size of the name*/
|
|
(char *)M_p_ucMsgSharedMemGetSenderNameOffset(p_ucOffset)/* The name*/
|
|
);
|
|
if
|
|
(
|
|
(uwNewChannel != C_uwNetInvalidChannel)&&
|
|
(!gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ubf1IsSlotInUse)
|
|
)
|
|
{
|
|
/* It is a new slot, so initialize it :*/
|
|
/* If an error occured during the initialisation, the slot is unvalidated*/
|
|
/* But a message is return with an NoError code, since we succeed in */
|
|
/* getting a message */
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ucRemoteSharedMemNameSize
|
|
=*M_p_ucMsgSharedMemGetSenderNameLengthOffset(p_ucOffset);
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_pcRemoteSharedMemName
|
|
= (char*)pMalloc(gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ucRemoteSharedMemNameSize);
|
|
if(gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_pcRemoteSharedMemName)
|
|
{
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_pcRemoteSharedMemNameMutex
|
|
= (char*)pMalloc(gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ucRemoteSharedMemNameSize-1+sizeof("Mutex"));
|
|
if(gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_pcRemoteSharedMemNameMutex)
|
|
{
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_pcRemoteSharedMemName,
|
|
M_p_ucMsgSharedMemGetSenderNameOffset(p_ucOffset),
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ucRemoteSharedMemNameSize
|
|
);
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_pcRemoteSharedMemNameMutex,
|
|
M_p_ucMsgSharedMemGetSenderNameOffset(p_ucOffset),
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ucRemoteSharedMemNameSize-1
|
|
);
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_pcRemoteSharedMemNameMutex +
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ucRemoteSharedMemNameSize-1,
|
|
"Mutex",
|
|
sizeof("Mutex")
|
|
);
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_eChannelStatus = E_ts_OK;
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ubf1IsSlotBroadcast = 0;
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ubf1IsSlotInUse = 1;
|
|
|
|
/* Set the new channel :*/
|
|
*p_uwChannel = uwNewChannel;
|
|
}
|
|
else
|
|
{
|
|
vFree((tdpPointer)gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_pcRemoteSharedMemName);
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ucRemoteSharedMemNameSize = 0;
|
|
}
|
|
}
|
|
else
|
|
gs_a_stL0PCWin95SharedMemChannels[uwNewChannel].m_ucRemoteSharedMemNameSize = 0;
|
|
}
|
|
else
|
|
/* This is not a new slot*/
|
|
*p_uwChannel = uwNewChannel;
|
|
|
|
/* If there are messages following the current one, shift them :*/
|
|
p_ucOffset =
|
|
M_p_ucMsgSharedMemGetFirstL0MsgOffset(gs_pvOwnSharedMem)/* the shared mem header*/
|
|
+ M_ucSharedMemSlotMsgHeaderSize(p_ucOffset) /* the read msg header*/
|
|
+ ulMessageBytes; /* the message*/
|
|
|
|
ulTotalBytesToShift = ulBytesToShift = 0;
|
|
/* Set ulMessageBytes to the number of bytes of the message plus */
|
|
/* the header of the shared memory, and plus the header of the msg :*/
|
|
ulMessageBytes =
|
|
ulMessageBytes +
|
|
C_ucSharedMemMsgHeaderSize +
|
|
M_ucSharedMemSlotMsgHeaderSize(p_ucOffset);
|
|
while(
|
|
(ulMessageBytes + ulTotalBytesToShift < gs_ulOwnMemoryLength)&&
|
|
(*M_p_ucMsgSharedMemGetIsMessageOffset(p_ucOffset) != 0xff))
|
|
{
|
|
ulBytesToShift =
|
|
M_ucSharedMemSlotMsgHeaderSize(p_ucOffset) +
|
|
sizeof(tdstNetMessage) +
|
|
M_p_stMsgSharedMemGetMessageOffset(p_ucOffset)->uwMessageSizeInBytes;
|
|
|
|
ulTotalBytesToShift +=ulBytesToShift;
|
|
p_ucOffset = p_ucOffset + ulBytesToShift;
|
|
}
|
|
/* reset p_ucOffsetTo the begining of the memory :*/
|
|
p_ucOffset = M_p_ucMsgSharedMemGetFirstL0MsgOffset(gs_pvOwnSharedMem);
|
|
if(ulTotalBytesToShift > gs_ulOwnMemoryLength)
|
|
{/* An invalid message was read, all the memory is reset :*/
|
|
/* I don't really known if I should return an error code since we
|
|
have a message. So, I considere it as no error
|
|
*/
|
|
ulTotalBytesToShift = 0;
|
|
}
|
|
|
|
/* If there are data to shift, just do it...*/
|
|
if(ulTotalBytesToShift >0)
|
|
memmove
|
|
(
|
|
p_ucOffset,/*Dest : the begining of the shared memory + the header*/
|
|
(unsigned char *)gs_pvOwnSharedMem +ulMessageBytes,
|
|
/*Src : the begining of the shared memory
|
|
+ the header + the message read*/
|
|
ulTotalBytesToShift /* bytes to shift*/
|
|
);
|
|
|
|
/* Set the end of the memory to an invalid value :*/
|
|
memset
|
|
(
|
|
p_ucOffset+ulTotalBytesToShift,
|
|
0xff,
|
|
gs_ulOwnMemoryLength-ulBytesToShift-C_ucSharedMemMsgHeaderSize
|
|
);
|
|
|
|
/* Relase the mutex and close the handler*/
|
|
ReleaseMutex(hOwnMutex);
|
|
CloseHandle(hOwnMutex);
|
|
return NetLib_E_es_NoError;
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : eL0PCWin95SharedFillRemoteMem
|
|
Puts a msg in a specify memory
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
a pointer to the memory
|
|
a string containing the name of the mutex to use
|
|
a string containing the name of the shared mem
|
|
an unsigned char containing the length of the share mem name
|
|
a pointer to the data to send
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
An tdeErrorStatus code
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 28, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
NetLib_tdeErrorStatus eL0PCWin95SharedFillRemoteMem
|
|
(
|
|
void *p_vSharedMem,
|
|
char *p_cRemoteSharedMemMutexName,
|
|
tdpPointer pDataToSend
|
|
)
|
|
{
|
|
HANDLE hMutexHandle;
|
|
unsigned char *p_ucOffset;
|
|
unsigned long ulMemoryShifted;
|
|
unsigned long ulTotalMem;
|
|
|
|
hMutexHandle = CreateMutex(NULL,FALSE,p_cRemoteSharedMemMutexName);
|
|
if(hMutexHandle == (HANDLE)C_pNull)
|
|
return NetLib_E_es_SharedMemMutexFailure;
|
|
while(WaitForSingleObject(hMutexHandle,0)!=WAIT_OBJECT_0);
|
|
/* Search for the place to write the new msg :*/
|
|
p_ucOffset = M_p_ucSharedMemMsgGetFirstMsgPosition(p_vSharedMem);
|
|
ulMemoryShifted = C_ucSharedMemMsgHeaderSize;
|
|
ulTotalMem = *((unsigned long *)M_p_ucSharedMemMsgGetMemSizeInBytesOffset(p_vSharedMem));
|
|
/* look for a free place*/
|
|
while
|
|
(
|
|
(ulMemoryShifted <= ulTotalMem)&&
|
|
(*M_p_ucMsgSharedMemGetIsMessageOffset(p_ucOffset)!=0xff)
|
|
)
|
|
{
|
|
ulMemoryShifted =
|
|
ulMemoryShifted +
|
|
M_ucSharedMemSlotMsgHeaderSize(p_ucOffset) +
|
|
sizeof(tdstNetMessage) +
|
|
M_p_stMsgSharedMemGetMessageOffset(p_ucOffset)->uwMessageSizeInBytes;
|
|
p_ucOffset =
|
|
p_ucOffset +
|
|
M_ucSharedMemSlotMsgHeaderSize(p_ucOffset) +
|
|
sizeof(tdstNetMessage) +
|
|
M_p_stMsgSharedMemGetMessageOffset(p_ucOffset)->uwMessageSizeInBytes;
|
|
}
|
|
/* Check if there is enought memory to write the msg*/
|
|
if
|
|
(
|
|
sizeof(tdstNetMessage)+
|
|
((tdstNetMessage*)pDataToSend)->uwMessageSizeInBytes +
|
|
M_ucSharedMemSlotMsgHeaderSizeWithNameLength(gs_ucOwnSharedMemNameLength) +
|
|
ulMemoryShifted
|
|
> ulTotalMem
|
|
)
|
|
{
|
|
ReleaseMutex(hMutexHandle);
|
|
CloseHandle(hMutexHandle);
|
|
return NetLib_E_es_EmissionInProgress;
|
|
}
|
|
|
|
/* Else, fill the msg header and copy the msg*/
|
|
*M_p_ucMsgSharedMemGetIsMessageOffset(p_ucOffset) = 0x00;
|
|
*M_p_ucMsgSharedMemGetSenderNameLengthOffset(p_ucOffset) = gs_ucOwnSharedMemNameLength;
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
M_p_ucMsgSharedMemGetSenderNameOffset(p_ucOffset),
|
|
gs_pcOwnSharedMemName,
|
|
gs_ucOwnSharedMemNameLength
|
|
);
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
(tdpPointer)M_p_stMsgSharedMemGetMessageOffset(p_ucOffset),
|
|
pDataToSend,
|
|
sizeof(tdstNetMessage)+((tdstNetMessage*)pDataToSend)->uwMessageSizeInBytes
|
|
);
|
|
|
|
ReleaseMutex(hMutexHandle);
|
|
CloseHandle(hMutexHandle);
|
|
return NetLib_E_es_NoError;
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : eL0PCWin95SharedMemSendData
|
|
Sends a message
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
A channel
|
|
A pointer to the new message
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
An tdeErrorStatus code
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 23, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Comment : a mutex is used to synchronize access to the shared memory
|
|
Sending a message consist in puting it into the memory shared of
|
|
each entry found in the table.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
NetLib_tdeErrorStatus eL0PCWin95SharedMemSendData(tduwNetChannel uwChannel,tdpPointer pData)
|
|
{
|
|
tdstL0PCWin95SharedMemChannel *p_stChannel;
|
|
NetLib_tdeErrorStatus eErrorReturned;
|
|
if
|
|
(
|
|
(uwChannel == C_uwNetInvalidChannel)||
|
|
(uwChannel > C_uwL0MaxNumberOfSharedMemChannels)
|
|
)
|
|
return NetLib_E_es_InvalidChannel;
|
|
|
|
p_stChannel = &gs_a_stL0PCWin95SharedMemChannels[uwChannel];
|
|
if(!p_stChannel->m_ubf1IsSlotInUse)
|
|
return NetLib_E_es_ChannelUninitialized;
|
|
|
|
if(p_stChannel->m_ubf1IsSlotBroadcast)
|
|
{
|
|
HANDLE hDefTableMutex;
|
|
HANDLE hCurrentSharedMem;
|
|
void *p_vCurrentSharedMem;
|
|
char *p_cCurrentSharedMemNameMutex;
|
|
unsigned char c_ucCurrentSlot;
|
|
unsigned char ucNumberOfSlot;
|
|
unsigned char ucSizeOfOneSlot;
|
|
unsigned char *p_ucSlotArray;
|
|
|
|
hDefTableMutex = CreateMutex(NULL,FALSE,p_stChannel->m_pcRemoteSharedMemNameMutex);
|
|
if(hDefTableMutex == (HANDLE)C_pNull)
|
|
return NetLib_E_es_SharedMemMutexFailure;
|
|
while(WaitForSingleObject(hDefTableMutex,0)!=WAIT_OBJECT_0);
|
|
/* We 've got the mutex :*/
|
|
ucNumberOfSlot = *M_p_ucDefTableSharedMemGetNumberOfSlotOffset(p_stChannel->m_pvRemoteSharedMem);
|
|
ucSizeOfOneSlot = *M_p_ucDefTableSharedMemGetSizeOfOneSlotOffset(p_stChannel->m_pvRemoteSharedMem);
|
|
p_ucSlotArray = M_p_ucDefTableSharedMemGetSlotArrayOffset(p_stChannel->m_pvRemoteSharedMem);
|
|
for(c_ucCurrentSlot = 0;c_ucCurrentSlot < ucNumberOfSlot; c_ucCurrentSlot++)
|
|
{
|
|
/* check wether the slot is a free one or not :*/
|
|
if
|
|
(
|
|
*M_p_ucDefTableShareMemGetIsFreeSlotOffset(&p_ucSlotArray[c_ucCurrentSlot*ucSizeOfOneSlot]) ==
|
|
C_ucDefTableSharedMemUsedSlot
|
|
)
|
|
{
|
|
if
|
|
(
|
|
(gs_ucOwnSharedMemNameLength!=
|
|
*M_p_ucMsgSharedMemGetSenderNameLengthOffset(&p_ucSlotArray[c_ucCurrentSlot*ucSizeOfOneSlot])) ||
|
|
(memcmp
|
|
(
|
|
M_p_cDefTableSharedMemGetNameOffset(&p_ucSlotArray[c_ucCurrentSlot*ucSizeOfOneSlot]),
|
|
gs_pcOwnSharedMemName,
|
|
gs_ucOwnSharedMemNameLength
|
|
)!= 0)
|
|
)
|
|
{
|
|
hCurrentSharedMem = CreateFileMapping
|
|
(
|
|
(HANDLE)0xFFFFFFFF,/* Handle of the file : 0xFFFFFFFF for memory block*/
|
|
NULL, /* Security attributes : NULL equals to system default security attributes*/
|
|
PAGE_READWRITE,/*Protection for mapping object*/
|
|
0,/*Maximum size high*/
|
|
1, /*It doesn't matter since it supposed to previously exist*/
|
|
M_p_cDefTableSharedMemGetNameOffset(&p_ucSlotArray[c_ucCurrentSlot*ucSizeOfOneSlot])/*Name*/
|
|
);
|
|
if
|
|
(
|
|
(hCurrentSharedMem!=(HANDLE)C_pNull)&&
|
|
(GetLastError()==ERROR_ALREADY_EXISTS)
|
|
)
|
|
{
|
|
p_vCurrentSharedMem = MapViewOfFile
|
|
(
|
|
hCurrentSharedMem, /* Handle of the shared file*/
|
|
FILE_MAP_ALL_ACCESS, /* Access to the file map*/
|
|
0,/*File offset high*/
|
|
0,/*File offser low*/
|
|
0/* I don't realy known if it is used to sepcify again the size of the memory block*/
|
|
);
|
|
if(p_vCurrentSharedMem != (void*)C_pNull)
|
|
{
|
|
p_cCurrentSharedMemNameMutex = (char*)
|
|
pMalloc(sizeof("Mutex")-1+(*M_p_ucDefTableSharedMemGetNameLengthOffset(&p_ucSlotArray[c_ucCurrentSlot*ucSizeOfOneSlot])));
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
p_cCurrentSharedMemNameMutex,
|
|
M_p_cDefTableSharedMemGetNameOffset(&p_ucSlotArray[c_ucCurrentSlot*ucSizeOfOneSlot]),
|
|
(*M_p_ucDefTableSharedMemGetNameLengthOffset(&p_ucSlotArray[c_ucCurrentSlot*ucSizeOfOneSlot]))-1
|
|
);
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
p_cCurrentSharedMemNameMutex + (*M_p_ucDefTableSharedMemGetNameLengthOffset(&p_ucSlotArray[c_ucCurrentSlot*ucSizeOfOneSlot]))-1,
|
|
"Mutex",
|
|
sizeof("Mutex")
|
|
);
|
|
|
|
eL0PCWin95SharedFillRemoteMem
|
|
(
|
|
p_vCurrentSharedMem,
|
|
p_cCurrentSharedMemNameMutex,
|
|
pData
|
|
);
|
|
UnmapViewOfFile(p_vCurrentSharedMem);
|
|
CloseHandle(hCurrentSharedMem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ReleaseMutex(hDefTableMutex);
|
|
CloseHandle(hDefTableMutex);
|
|
return NetLib_E_es_NoError;
|
|
}
|
|
else
|
|
{
|
|
/* Non broadcast sending msg :*/
|
|
p_stChannel->m_hRemoteSharedMem = CreateFileMapping
|
|
(
|
|
(HANDLE)0xFFFFFFFF,/* Handle of the file : 0xFFFFFFFF for memory block*/
|
|
NULL, /* Security attributes : NULL equals to system default security attributes*/
|
|
PAGE_READWRITE,/*Protection for mapping object*/
|
|
0,/*Maximum size high*/
|
|
1, /*Maximum size low*/
|
|
p_stChannel->m_pcRemoteSharedMemName /*Name*/
|
|
);
|
|
|
|
if
|
|
(
|
|
(p_stChannel->m_hRemoteSharedMem == (HANDLE)C_pNull)||
|
|
(GetLastError()!=ERROR_ALREADY_EXISTS)
|
|
)
|
|
return NetLib_E_es_SharedMemCreateFailure;
|
|
|
|
p_stChannel->m_pvRemoteSharedMem = MapViewOfFile
|
|
(
|
|
p_stChannel->m_hRemoteSharedMem, /* Handle of the shared file*/
|
|
FILE_MAP_ALL_ACCESS, /* Access to the file map*/
|
|
0,/*File offset high*/
|
|
0,/*File offser low*/
|
|
0/* I don't realy known if it is used to sepcify again the size of the memory block*/
|
|
);
|
|
if(p_stChannel->m_pvRemoteSharedMem ==(void*)C_pNull)
|
|
{
|
|
CloseHandle(p_stChannel->m_hRemoteSharedMem);
|
|
return NetLib_E_es_SharedMemMapFailure;
|
|
}
|
|
|
|
eErrorReturned = eL0PCWin95SharedFillRemoteMem
|
|
(
|
|
p_stChannel->m_pvRemoteSharedMem,
|
|
p_stChannel->m_pcRemoteSharedMemNameMutex,
|
|
pData
|
|
);
|
|
UnmapViewOfFile(p_stChannel->m_pvRemoteSharedMem);
|
|
p_stChannel->m_pvRemoteSharedMem = (void*)C_pNull;
|
|
CloseHandle(p_stChannel->m_hRemoteSharedMem);
|
|
p_stChannel->m_hRemoteSharedMem = (HANDLE)C_pNull;
|
|
return eErrorReturned;
|
|
}
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : eL0PCWin95SharedMemQueryChannelStatus
|
|
Returns the status of a given channel
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
A channel
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
An tdeErrorStatus code
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May , 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
NetLib_tdeErrorStatus eL0PCWin95SharedMemQueryChannelStatus(tduwNetChannel uwChannel)
|
|
{
|
|
return NetLib_E_es_NoError;
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : vL0PCWin95SharedMemCloseProtocol
|
|
Closes a channel in the array of channels:
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
The channel to close
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
None
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 28, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
void vL0PCWin95SharedMemCloseChannel(tduwNetChannel uwOldChannel)
|
|
{
|
|
tdstL0PCWin95SharedMemChannel *p_stOldChannel;
|
|
if(gs_a_stL0PCWin95SharedMemChannels[uwOldChannel].m_ubf1IsSlotInUse)
|
|
{
|
|
p_stOldChannel = &gs_a_stL0PCWin95SharedMemChannels[uwOldChannel];
|
|
if(p_stOldChannel->m_ubf1IsSlotBroadcast)
|
|
{
|
|
HANDLE hMutex;
|
|
unsigned char ucSlot;
|
|
/* This is a broadcast slot:*/
|
|
hMutex = CreateMutex(NULL,FALSE,p_stOldChannel->m_pcRemoteSharedMemNameMutex);
|
|
if(hMutex != (HANDLE)C_pNull)
|
|
{
|
|
while(WaitForSingleObject(hMutex,0)!=WAIT_OBJECT_0);
|
|
ucSlot = (gs_pcOwnSharedMemName[24] - '1' + 1) *100
|
|
+ (1 + gs_pcOwnSharedMemName[25] - '1') *10
|
|
+ (gs_pcOwnSharedMemName[26] - '1' + 1);
|
|
if(
|
|
ucSlot <
|
|
*M_p_ucDefTableSharedMemGetNumberOfSlotOffset(p_stOldChannel->m_pvRemoteSharedMem))
|
|
{
|
|
unsigned char *p_ucSlotArray;
|
|
p_ucSlotArray = M_p_ucDefTableSharedMemGetSlotArrayOffset(p_stOldChannel->m_pvRemoteSharedMem);
|
|
p_ucSlotArray = &p_ucSlotArray[ucSlot*(*M_p_ucDefTableSharedMemGetSizeOfOneSlotOffset(p_stOldChannel->m_pvRemoteSharedMem))];
|
|
*M_p_ucDefTableShareMemGetIsFreeSlotOffset(p_ucSlotArray) = C_ucDefTableSharedMemUnusedSlot;
|
|
*M_p_ucDefTableSharedMemGetNextFreeSlotOffset(p_ucSlotArray) = *M_p_ucDefTableSharedMemGetFreeSlotOffset(p_stOldChannel->m_pvRemoteSharedMem);
|
|
*M_p_ucDefTableSharedMemGetFreeSlotOffset(p_stOldChannel->m_pvRemoteSharedMem) = ucSlot;
|
|
}
|
|
ReleaseMutex(hMutex);
|
|
CloseHandle(hMutex);
|
|
}
|
|
UnmapViewOfFile(p_stOldChannel->m_pvRemoteSharedMem);
|
|
p_stOldChannel->m_pvRemoteSharedMem = (void*)C_pNull;
|
|
CloseHandle(p_stOldChannel->m_hRemoteSharedMem);
|
|
p_stOldChannel->m_hRemoteSharedMem = (HANDLE)C_pNull;
|
|
p_stOldChannel->m_ulRemoteSharedMemLength = 0;
|
|
}
|
|
|
|
vFree(p_stOldChannel->m_pcRemoteSharedMemName);
|
|
p_stOldChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
vFree(p_stOldChannel->m_pcRemoteSharedMemNameMutex);
|
|
p_stOldChannel->m_pcRemoteSharedMemNameMutex = (char*)C_pNull;
|
|
p_stOldChannel->m_ucRemoteSharedMemNameSize = 0;
|
|
p_stOldChannel->m_eChannelStatus = E_ts_Invalid;
|
|
p_stOldChannel->m_ubf1IsSlotInUse = 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : vL0PCWin95SharedMemCloseProtocol
|
|
Closes the protocol :
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
None
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
None
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 23, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Comment : a mutex is used to synchronize access to the shared memory
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
void vL0PCWin95SharedMemCloseProtocol(void)
|
|
{
|
|
tduwNetChannel c_uwCurrentChannel;
|
|
for
|
|
(
|
|
c_uwCurrentChannel = 0;
|
|
c_uwCurrentChannel < C_uwL0MaxNumberOfSharedMemChannels;
|
|
c_uwCurrentChannel++
|
|
)
|
|
{
|
|
if(gs_a_stL0PCWin95SharedMemChannels[c_uwCurrentChannel].m_ubf1IsSlotInUse)
|
|
vL0PCWin95SharedMemCloseChannel(c_uwCurrentChannel);
|
|
}
|
|
|
|
/* Now close the own shared memory*/
|
|
UnmapViewOfFile(gs_pvOwnSharedMem);
|
|
gs_pvOwnSharedMem = (void *)C_pNull;
|
|
CloseHandle(gs_hOwnSharedMem);
|
|
gs_hOwnSharedMem = (HANDLE)C_pNull;
|
|
gs_ulOwnMemoryLength= 0;
|
|
vFree(gs_pcOwnSharedMemName);
|
|
gs_pcOwnSharedMemName = C_pNull;
|
|
gs_ucOwnSharedMemNameLength = 0;
|
|
vFree(gs_pcOwnSharedMemMutexName);
|
|
gs_pcOwnSharedMemMutexName = C_pNull;
|
|
|
|
vLevel1RemoveProtocol(E_Net_pr_Windows95SharedMemProtocol);
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : eL0Win95PCSharedMemSetupOwnMem
|
|
Setup the reading shared memory
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
the length of our memory
|
|
ucFreeSlot : an index
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
An tdeErrorStatus code
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 28, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
NetLib_tdeErrorStatus eL0Win95PCSharedMemSetupOwnMem
|
|
(
|
|
unsigned long ulMemLength,
|
|
unsigned char ucFreeSlot,
|
|
char *p_szDefTableSharedMemName,
|
|
unsigned char ucNameLength
|
|
)
|
|
{
|
|
unsigned short uwDigit;
|
|
|
|
if(gs_hOwnSharedMem!=(HANDLE)C_pNull)
|
|
/* If it has been already initialize, it is no use to do it again*/
|
|
return NetLib_E_es_NoError;
|
|
|
|
gs_ucOwnSharedMemNameLength = ucNameLength -1 + sizeof("NetLib_1_0_SharedMemory_xxx");
|
|
gs_pcOwnSharedMemName = (char *)pMalloc(gs_ucOwnSharedMemNameLength);
|
|
|
|
if(gs_pcOwnSharedMemName== C_pNull)
|
|
return NetLib_E_es_NotEnoughMemory;
|
|
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
gs_pcOwnSharedMemName,
|
|
"NetLib_1_0_SharedMemory_xxx",
|
|
sizeof("NetLib_1_0_SharedMemory_xxx")-1
|
|
);
|
|
|
|
gs_pcOwnSharedMemName[24] = '1' + (ucFreeSlot/100 -1);
|
|
uwDigit = ucFreeSlot - (ucFreeSlot/100)*100;
|
|
gs_pcOwnSharedMemName[25] = '1' + (uwDigit/10 -1);
|
|
uwDigit = uwDigit - (uwDigit/10)*10;
|
|
gs_pcOwnSharedMemName[26] = '1' + (uwDigit-1);
|
|
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
gs_pcOwnSharedMemName + sizeof("NetLib_1_0_SharedMemory_xxx")-1,
|
|
p_szDefTableSharedMemName,
|
|
ucNameLength
|
|
);
|
|
/* Create the own shared memory*/
|
|
gs_ulOwnMemoryLength = ulMemLength;
|
|
gs_hOwnSharedMem = CreateFileMapping
|
|
(
|
|
(HANDLE)0xFFFFFFFF,/* Handle of the file : 0xFFFFFFFF for memory block*/
|
|
NULL, /* Security attributes : NULL equals to system default security attributes*/
|
|
PAGE_READWRITE,/*Protection for mapping object*/
|
|
0,/*Maximum size high*/
|
|
gs_ulOwnMemoryLength, /*Maximum size low*/
|
|
gs_pcOwnSharedMemName /*Name*/
|
|
);
|
|
|
|
if(
|
|
(gs_hOwnSharedMem == (HANDLE)C_pNull)||/* An error occured*/
|
|
(GetLastError()==ERROR_ALREADY_EXISTS))/* The table is corrupted*/
|
|
{
|
|
vFree((tdpPointer)gs_pcOwnSharedMemName);
|
|
gs_ucOwnSharedMemNameLength = 0;
|
|
gs_pcOwnSharedMemName = (char *)C_pNull;
|
|
|
|
return NetLib_E_es_SharedMemCreateFailure;
|
|
}
|
|
|
|
/* Now map the new file :*/
|
|
gs_pvOwnSharedMem = MapViewOfFile
|
|
(
|
|
gs_hOwnSharedMem, /* Handle of the shared file*/
|
|
FILE_MAP_ALL_ACCESS, /* Access to the file map*/
|
|
0,/*File offset high*/
|
|
0,/*File offser low*/
|
|
gs_ulOwnMemoryLength/* I don't realy known if it is used to sepcify again the size of the memory block*/
|
|
);
|
|
if(gs_pvOwnSharedMem == (void *)C_pNull)
|
|
{
|
|
CloseHandle(gs_hOwnSharedMem);
|
|
gs_hOwnSharedMem = (HANDLE)C_pNull;
|
|
vFree((tdpPointer)gs_pcOwnSharedMemName);
|
|
gs_ucOwnSharedMemNameLength = 0;
|
|
gs_pcOwnSharedMemName = (char *)C_pNull;
|
|
|
|
return NetLib_E_es_SharedMemMapFailure;
|
|
}
|
|
|
|
/* Initialise the mutex name:*/
|
|
gs_pcOwnSharedMemMutexName = pMalloc(gs_ucOwnSharedMemNameLength -1 + sizeof("Mutex"));
|
|
if(gs_pcOwnSharedMemMutexName == (char *)C_pNull)
|
|
{
|
|
UnmapViewOfFile(gs_pvOwnSharedMem);
|
|
gs_pvOwnSharedMem = (void *)C_pNull;
|
|
CloseHandle(gs_hOwnSharedMem);
|
|
gs_hOwnSharedMem = (HANDLE)C_pNull;
|
|
|
|
vFree((tdpPointer)gs_pcOwnSharedMemName);
|
|
gs_pcOwnSharedMemName = (char *)C_pNull;
|
|
gs_ucOwnSharedMemNameLength = 0;
|
|
|
|
return NetLib_E_es_NotEnoughMemory;
|
|
}
|
|
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
gs_pcOwnSharedMemMutexName,
|
|
gs_pcOwnSharedMemName,
|
|
gs_ucOwnSharedMemNameLength-1
|
|
);
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
(char*)gs_pcOwnSharedMemMutexName+gs_ucOwnSharedMemNameLength-1,
|
|
"Mutex",
|
|
sizeof"Mutex"
|
|
);
|
|
|
|
/* The mutex is not used for this access since the own shared mem*/
|
|
/* has not been added to any def table*/
|
|
/* initialise the new memory :*/
|
|
memset(gs_pvOwnSharedMem,0xff,gs_ulOwnMemoryLength);
|
|
/*Fill the header :*/
|
|
*((unsigned long*)M_p_ucMsgSharedMemGetMemSizeInBytesOffset(gs_pvOwnSharedMem)) = gs_ulOwnMemoryLength;
|
|
|
|
return NetLib_E_es_NoError;
|
|
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : eL0SetupWin95PCSharedMem
|
|
Setup of the shared memory protocol
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
A zero-terminate string corresponding to the name of the table
|
|
An unsigned long specifying the length of the string
|
|
An unsigned long specifying the length of the memories shared
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
An tdeErrorStatus code
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 28, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Comment : a mutex is used to synchronize access to the shared memory
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eL0SetupWin95PCSharedMem(char *p_szDefTableSharedMemName,unsigned char ucNameLength, unsigned long ulMemoryLength)
|
|
{
|
|
tduwNetChannel uwChannel;
|
|
tdstL0PCWin95SharedMemChannel *p_stNewChannel;
|
|
unsigned char b_ucFirstCall;
|
|
HANDLE hMutexHandle;
|
|
unsigned char *p_ucSlotArray;
|
|
unsigned char c_ucCount;
|
|
unsigned short uwNumberOfSlot;
|
|
unsigned char ucSizeOfOneSlot;
|
|
unsigned char ucFreeSlot;
|
|
NetLib_tdeErrorStatus eErrorReturned;
|
|
|
|
/* Check that parameters are valid */
|
|
if(ucNameLength > C_ucMaxNameSize)
|
|
return NetLib_E_es_SharedMemNameTooLong;
|
|
|
|
/* get a free slot :*/
|
|
uwChannel = uwL0PCWin95SharedMemGetSlot(ucNameLength,p_szDefTableSharedMemName);
|
|
|
|
if(uwChannel == C_uwNetInvalidChannel)
|
|
return NetLib_E_es_NoChannelAvaible;
|
|
|
|
p_stNewChannel = &gs_a_stL0PCWin95SharedMemChannels[uwChannel];
|
|
|
|
if(p_stNewChannel->m_ubf1IsSlotInUse)
|
|
return NetLib_E_es_SharedMemDefTableAlreadyExist;
|
|
|
|
/* Init the new channel*/
|
|
p_stNewChannel->m_pcRemoteSharedMemName = pMalloc(ucNameLength);
|
|
if(p_stNewChannel->m_pcRemoteSharedMemName == (char*)C_pNull)
|
|
return NetLib_E_es_NotEnoughMemory;
|
|
p_stNewChannel->m_pcRemoteSharedMemNameMutex = pMalloc(ucNameLength-1+sizeof("Mutex"));
|
|
if(p_stNewChannel->m_pcRemoteSharedMemNameMutex == (char*)C_pNull)
|
|
{
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemName);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
return NetLib_E_es_NotEnoughMemory;
|
|
}
|
|
p_stNewChannel->m_ucRemoteSharedMemNameSize = ucNameLength;
|
|
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
p_stNewChannel->m_pcRemoteSharedMemName,
|
|
p_szDefTableSharedMemName,
|
|
ucNameLength
|
|
);
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
p_stNewChannel->m_pcRemoteSharedMemNameMutex,
|
|
p_szDefTableSharedMemName,
|
|
ucNameLength-1
|
|
);
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
p_stNewChannel->m_pcRemoteSharedMemNameMutex+ucNameLength-1,
|
|
"Mutex",
|
|
sizeof("Mutex")
|
|
);
|
|
|
|
/* First of all, create the file mapping :*/
|
|
p_stNewChannel->m_ulRemoteSharedMemLength = ulMemoryLength;
|
|
p_stNewChannel->m_hRemoteSharedMem = CreateFileMapping
|
|
(
|
|
(HANDLE)0xFFFFFFFF,/* Handle of the file : 0xFFFFFFFF for memory block*/
|
|
NULL, /* Security attributes : NULL equals to system default security attributes*/
|
|
PAGE_READWRITE,/*Protection for mapping object*/
|
|
0,/*Maximum size high*/
|
|
p_stNewChannel->m_ulRemoteSharedMemLength,/*Maximum size low*/
|
|
p_stNewChannel->m_pcRemoteSharedMemName/*Name*/
|
|
);
|
|
|
|
if(p_stNewChannel->m_hRemoteSharedMem == (HANDLE)C_pNull)
|
|
{
|
|
/* An error occured*/
|
|
p_stNewChannel->m_ulRemoteSharedMemLength = 0;
|
|
p_stNewChannel->m_ucRemoteSharedMemNameSize = 0;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemName);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemNameMutex);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
return NetLib_E_es_SharedMemCreateFailure;
|
|
}
|
|
|
|
/* Check if the table was not still created :*/
|
|
/* if the table already exists, GetLastError returns ERROR_ALREADY_EXISTS*/
|
|
/* otherwise, it returns 0 */
|
|
b_ucFirstCall = GetLastError()!=ERROR_ALREADY_EXISTS;
|
|
|
|
/* Now get a pointer to the memory */
|
|
p_stNewChannel->m_pvRemoteSharedMem = MapViewOfFile
|
|
(
|
|
p_stNewChannel->m_hRemoteSharedMem, /* Handle of the shared file*/
|
|
FILE_MAP_ALL_ACCESS, /* Access to the file map*/
|
|
0,/*File offset high*/
|
|
0,/*File offser low*/
|
|
p_stNewChannel->m_ulRemoteSharedMemLength/* I don't realy known if it is used to sepcify again the size of the memory block*/
|
|
);
|
|
|
|
if(p_stNewChannel->m_pvRemoteSharedMem ==(void *)C_pNull)
|
|
{
|
|
/* Creation failure :*/
|
|
CloseHandle(p_stNewChannel->m_hRemoteSharedMem);
|
|
p_stNewChannel->m_hRemoteSharedMem = (HANDLE)C_pNull;
|
|
|
|
p_stNewChannel->m_ulRemoteSharedMemLength = 0;
|
|
p_stNewChannel->m_ucRemoteSharedMemNameSize = 0;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemName);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemNameMutex);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
|
|
/* An error occured :*/
|
|
return NetLib_E_es_SharedMemMapFailure;
|
|
}
|
|
|
|
/* Here we have a valid handle and a valid pointer*/
|
|
/* Create a mutex to get access the memory :*/
|
|
hMutexHandle = CreateMutex
|
|
(
|
|
NULL,/*Security attributes*/
|
|
FALSE,/* Initially not owned*/
|
|
p_stNewChannel->m_pcRemoteSharedMemNameMutex/*Name of the mutex*/
|
|
);
|
|
|
|
if(hMutexHandle == (HANDLE)C_pNull)
|
|
{
|
|
/* An error occured, access to memory should not be done*/
|
|
UnmapViewOfFile(p_stNewChannel->m_pvRemoteSharedMem);
|
|
CloseHandle(p_stNewChannel->m_hRemoteSharedMem);
|
|
p_stNewChannel->m_hRemoteSharedMem = (HANDLE)C_pNull;
|
|
|
|
p_stNewChannel->m_ulRemoteSharedMemLength = 0;
|
|
p_stNewChannel->m_ucRemoteSharedMemNameSize = 0;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemName);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemNameMutex);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
|
|
return NetLib_E_es_SharedMemMutexFailure;
|
|
}
|
|
/*Mutex enables synchronisation for the memory access*/
|
|
while(WaitForSingleObject(hMutexHandle,0)!=WAIT_OBJECT_0);
|
|
|
|
/* Set p_ucSlotArray to the begining of slots :*/
|
|
p_ucSlotArray = M_p_ucDefTableSharedMemGetSlotArrayOffset
|
|
(p_stNewChannel->m_pvRemoteSharedMem);
|
|
|
|
/* Here we have the mutex, so we can start working on the memory*/
|
|
if(b_ucFirstCall)
|
|
{
|
|
/* Initialise the definition table, since it has just been created*/
|
|
|
|
/* Fill the header of the DefTable*/
|
|
uwNumberOfSlot =
|
|
(unsigned short)p_stNewChannel->m_ulRemoteSharedMemLength - C_ucDefTableSharedMemHeaderSize;
|
|
uwNumberOfSlot = uwNumberOfSlot/(C_ucMaxNameSize + C_ucDefTableSharedMemSlotHeaderSize);
|
|
/* Initialize the header :*/
|
|
*(M_p_ucDefTableSharedMemGetNumberOfSlotOffset(p_stNewChannel->m_pvRemoteSharedMem))
|
|
= (unsigned char)uwNumberOfSlot;
|
|
ucSizeOfOneSlot = C_ucMaxNameSize + C_ucDefTableSharedMemSlotHeaderSize;
|
|
*(M_p_ucDefTableSharedMemGetSizeOfOneSlotOffset(p_stNewChannel->m_pvRemoteSharedMem)) =
|
|
ucSizeOfOneSlot;
|
|
*(M_p_ucDefTableSharedMemGetFreeSlotOffset(p_stNewChannel->m_pvRemoteSharedMem)) =
|
|
0;
|
|
|
|
for(c_ucCount = 0;c_ucCount < uwNumberOfSlot;c_ucCount++)
|
|
{
|
|
*M_p_ucDefTableShareMemGetIsFreeSlotOffset(&p_ucSlotArray[c_ucCount*ucSizeOfOneSlot])
|
|
= C_ucDefTableSharedMemUnusedSlot;
|
|
*M_p_ucDefTableSharedMemGetNextFreeSlotOffset(&p_ucSlotArray[c_ucCount*ucSizeOfOneSlot])
|
|
= c_ucCount+1;
|
|
}
|
|
/*Set the last to an invalid value*/
|
|
*M_p_ucDefTableShareMemGetIsFreeSlotOffset(&p_ucSlotArray[(uwNumberOfSlot-1)*ucSizeOfOneSlot])
|
|
= C_ucDefTableSharedMemUnusedSlot;
|
|
*M_p_ucDefTableSharedMemGetNextFreeSlotOffset(&p_ucSlotArray[(uwNumberOfSlot-1)*ucSizeOfOneSlot])
|
|
= (unsigned char)-1;
|
|
}
|
|
else
|
|
{
|
|
uwNumberOfSlot = (unsigned short)(*(M_p_ucDefTableSharedMemGetNumberOfSlotOffset(p_stNewChannel->m_pvRemoteSharedMem)));
|
|
ucSizeOfOneSlot =*(M_p_ucDefTableSharedMemGetSizeOfOneSlotOffset(p_stNewChannel->m_pvRemoteSharedMem)) ;
|
|
}
|
|
|
|
/* Get a free slot :*/
|
|
ucFreeSlot = *M_p_ucDefTableSharedMemGetFreeSlotOffset(p_stNewChannel->m_pvRemoteSharedMem);
|
|
|
|
if(ucFreeSlot == (unsigned char)-1)
|
|
{/* the table is full*/
|
|
ReleaseMutex(hMutexHandle);
|
|
CloseHandle(hMutexHandle);
|
|
|
|
UnmapViewOfFile(p_stNewChannel->m_pvRemoteSharedMem);
|
|
CloseHandle(p_stNewChannel->m_hRemoteSharedMem);
|
|
p_stNewChannel->m_hRemoteSharedMem = (HANDLE)C_pNull;
|
|
|
|
p_stNewChannel->m_ulRemoteSharedMemLength = 0;
|
|
p_stNewChannel->m_ucRemoteSharedMemNameSize = 0;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemName);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemNameMutex);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
|
|
return NetLib_E_es_SharedMemDefTableFull;
|
|
}
|
|
|
|
eErrorReturned = eL0Win95PCSharedMemSetupOwnMem(ulMemoryLength,ucFreeSlot,p_szDefTableSharedMemName,ucNameLength);
|
|
if(eErrorReturned != NetLib_E_es_NoError)
|
|
{
|
|
ReleaseMutex(hMutexHandle);
|
|
CloseHandle(hMutexHandle);
|
|
|
|
UnmapViewOfFile(p_stNewChannel->m_pvRemoteSharedMem);
|
|
CloseHandle(p_stNewChannel->m_hRemoteSharedMem);
|
|
p_stNewChannel->m_hRemoteSharedMem = (HANDLE)C_pNull;
|
|
|
|
p_stNewChannel->m_ulRemoteSharedMemLength = 0;
|
|
p_stNewChannel->m_ucRemoteSharedMemNameSize = 0;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemName);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
vFree(p_stNewChannel->m_pcRemoteSharedMemNameMutex);
|
|
p_stNewChannel->m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
|
|
return eErrorReturned;
|
|
}
|
|
/* Since we succed in creating an own shared memory, put it in the table*/
|
|
|
|
/* But first, set the new free slot :*/
|
|
*M_p_ucDefTableSharedMemGetFreeSlotOffset(p_stNewChannel->m_pvRemoteSharedMem)
|
|
= *M_p_ucDefTableSharedMemGetNextFreeSlotOffset(&p_ucSlotArray[ucFreeSlot*ucSizeOfOneSlot]);
|
|
|
|
/*Put the length of the name :*/
|
|
*M_p_ucDefTableShareMemGetIsFreeSlotOffset(&p_ucSlotArray[ucFreeSlot*ucSizeOfOneSlot])
|
|
= 0x00;
|
|
*M_p_ucDefTableSharedMemGetNameLengthOffset(&p_ucSlotArray[ucFreeSlot*ucSizeOfOneSlot])
|
|
= gs_ucOwnSharedMemNameLength;
|
|
/*Put the name of the own shared mem :*/
|
|
g_pfn_vNetMemcpy
|
|
(
|
|
M_p_cDefTableSharedMemGetNameOffset(&p_ucSlotArray[ucFreeSlot*ucSizeOfOneSlot]),
|
|
gs_pcOwnSharedMemName,
|
|
gs_ucOwnSharedMemNameLength
|
|
);
|
|
|
|
p_stNewChannel->m_eChannelStatus = E_ts_OK;
|
|
p_stNewChannel->m_ubf1IsSlotInUse = 1;
|
|
p_stNewChannel->m_ubf1IsSlotBroadcast = 1;
|
|
/* We have finish with the table, so restore the mutex :*/
|
|
ReleaseMutex(hMutexHandle);
|
|
CloseHandle(hMutexHandle);
|
|
|
|
/* Initialisation is completed, we can now return*/
|
|
gs_bL0PCWin95SharedMemInitState = gs_bL0PCWin95SharedMemInitState |0x02;
|
|
return NetLib_E_es_NoError;
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : vL0PCWin95SharedMemOpenProtocol
|
|
Setup of the shared memory protocol
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
A tdstNetProtocolInterface to fill
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
None
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : May 23, 96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
void _NET_CALLING_CONV_ vL0PCWin95SharedMemOpenProtocol(void)
|
|
{
|
|
unsigned char c_ucCount;
|
|
tdstNetProtocolInterface *p_stProtocolInterface;
|
|
|
|
p_stProtocolInterface=pstLevel1AddProtocol();
|
|
|
|
gs_bL0PCWin95SharedMemInitState = 0x00;
|
|
|
|
p_stProtocolInterface->eProtocol = E_Net_pr_Windows95SharedMemProtocol;
|
|
p_stProtocolInterface->fn_uwStartChannelScan = uwL0PCWin95SharedMemStartChannelScan;
|
|
p_stProtocolInterface->fn_uwStartBroadcastChannelScan = uwL0PCWin95SharedMemStartBroadcastChannelScan;
|
|
p_stProtocolInterface->fn_uwNextChannel = uwL0PCWin95SharedMemNextChannel;
|
|
p_stProtocolInterface->fn_uwNextBroadcastChannel = uwL0PCWin95SharedMemNextBroadcastChannel;
|
|
p_stProtocolInterface->fn_eReadData = eL0PCWin95SharedMemReadData;
|
|
p_stProtocolInterface->fn_eSendData = eL0PCWin95SharedMemSendData;
|
|
p_stProtocolInterface->fn_eQueryChannelStatus = eL0PCWin95SharedMemQueryChannelStatus;
|
|
p_stProtocolInterface->fn_vCloseChannel = vL0PCWin95SharedMemCloseChannel;
|
|
p_stProtocolInterface->fn_vLevel0NetEngine = (tdfn_vLevel0NetEngine)C_pNull;
|
|
p_stProtocolInterface->fn_vLevel0CloseProtocol = vL0PCWin95SharedMemCloseProtocol;
|
|
p_stProtocolInterface->eIsInternet = 0;
|
|
|
|
/* Initialise the global variables: */
|
|
gs_hOwnSharedMem = (HANDLE)C_pNull;
|
|
gs_pvOwnSharedMem = (void *)C_pNull;
|
|
gs_ulOwnMemoryLength = 0;
|
|
|
|
gs_pcOwnSharedMemName = (char *)C_pNull;
|
|
gs_pcOwnSharedMemMutexName = (char*)C_pNull;
|
|
gs_ucOwnSharedMemNameLength = 0;
|
|
for
|
|
(
|
|
c_ucCount = 0;
|
|
c_ucCount < C_uwL0MaxNumberOfSharedMemChannels;
|
|
c_ucCount++
|
|
)
|
|
{
|
|
gs_a_stL0PCWin95SharedMemChannels[c_ucCount].m_ulRemoteSharedMemLength = (unsigned long)0;
|
|
gs_a_stL0PCWin95SharedMemChannels[c_ucCount].m_hRemoteSharedMem = (HANDLE)C_pNull;
|
|
gs_a_stL0PCWin95SharedMemChannels[c_ucCount].m_pvRemoteSharedMem = (void *)C_pNull;
|
|
gs_a_stL0PCWin95SharedMemChannels[c_ucCount].m_pcRemoteSharedMemName = (char*)C_pNull;
|
|
gs_a_stL0PCWin95SharedMemChannels[c_ucCount].m_pcRemoteSharedMemNameMutex =(char*)C_pNull;
|
|
gs_a_stL0PCWin95SharedMemChannels[c_ucCount].m_eChannelStatus = E_ts_Invalid;
|
|
gs_a_stL0PCWin95SharedMemChannels[c_ucCount].m_ucRemoteSharedMemNameSize = (unsigned char)0;
|
|
gs_a_stL0PCWin95SharedMemChannels[c_ucCount].m_ubf1IsSlotInUse = 0;
|
|
gs_a_stL0PCWin95SharedMemChannels[c_ucCount].m_ubf1IsSlotBroadcast = 0;
|
|
}
|
|
gs_bL0PCWin95SharedMemInitState = gs_bL0PCWin95SharedMemInitState |0x01;
|
|
}
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Description : eL0PCWin95SharedMemIsProtocolSet
|
|
Check if the protocol is avaible for use or not
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Input :
|
|
none
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Output :
|
|
NetLib_E_es_ProtocolNotInitialized : the vLevel0SetupWin95PCSharedMemInterface has not
|
|
been called yet or it has failed, the application should call the level 2
|
|
eInitializeGlobalData function.
|
|
NetLib_E_es_SharedMemNoName : the eL0SetupWin95PCSharedMem has not been called yet. The
|
|
protocol has been correctly initialised, it can be used, but it won't give any
|
|
results since no port is avaible. The application should call it.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Creation date : June 4,96
|
|
Author : Albert Pais
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
*/
|
|
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eL0PCWin95SharedMemIsProtocolSet(void)
|
|
{
|
|
if(!(gs_bL0PCWin95SharedMemInitState&0x01))
|
|
return NetLib_E_es_ProtocolNotInitialized;
|
|
if(!(gs_bL0PCWin95SharedMemInitState&0x02))
|
|
return NetLib_E_es_SharedMemNoName;
|
|
|
|
return NetLib_E_es_True;
|
|
}
|