reman3/Rayman_X/cpa/tempgrp/NET/l0shamem.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;
}