Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1268 lines
36 KiB

//---------------------------------------------------------------
// Copyright (c)1998 Microsoft Corporation, All Rights Reserved.
//
// conn.cpp
//
// Connection mapping between sockets and CCONNECTION objects.
//
// Author:
//
// Edward Reus (edwardr) 02-26-98 Initial coding.
//
//---------------------------------------------------------------
#include "precomp.h"
#include <userenv.h>
#include <time.h>
#include <malloc.h>
#include <shlwapi.h>
#ifdef DBG_MEM
static LONG g_lCConnectionCount = 0;
#endif
extern HINSTANCE g_hInst; // Instance of ircamera.dll
//------------------------------------------------------------------------
// CCONNECTION::CCONNECTION()
//
//------------------------------------------------------------------------
CCONNECTION::CCONNECTION( IN DWORD dwKind,
IN SOCKET Socket,
IN HANDLE hIoCP,
IN CSCEP_CONNECTION *pScepConnection,
IN BOOL fSaveAsUPF )
{
this->SetKind(dwKind);
m_pszServiceName = 0;
m_ListenSocket = INVALID_SOCKET;
m_Socket = Socket;
m_hFile = INVALID_HANDLE_VALUE;
m_pszPathPlusFileName = 0;
m_dwFileBytesWritten = 0;
m_lPendingReads = 0;
// m_lMaxPendingReads is set in SetKind().
m_lPendingWrites = 0;
// m_lMaxPendingWrites is set in SetKind().
m_dwJpegOffset = 0;
m_fSaveAsUPF = fSaveAsUPF;
m_dwUpfBytes = 0;
m_dwBytesWritten = 0;
m_fReceiveComplete = FALSE;
m_fImpersonating = FALSE;
m_pScepConnection = pScepConnection;
// If the new connection is to a camera, then tell the system that
// we don't want it to hibrenate while the connection is active.
if (m_dwKind != PACKET_KIND_LISTEN)
{
#ifdef USE_WINNT_CALLS
m_ExecutionState
= SetThreadExecutionState( ES_SYSTEM_REQUIRED|ES_CONTINUOUS );
#else
#pragma message("Missing important call: SetThreadExecutionState on Windows9x ")
#endif
}
}
//------------------------------------------------------------------------
// CCONNECTION::~CCONNECTION()
//
//------------------------------------------------------------------------
CCONNECTION::~CCONNECTION()
{
if (m_pszServiceName)
{
FreeMemory(m_pszServiceName);
}
if ( (m_dwKind == PACKET_KIND_LISTEN)
&& (m_ListenSocket != INVALID_SOCKET))
{
closesocket(m_ListenSocket);
}
if (m_Socket != INVALID_SOCKET)
{
closesocket(m_Socket);
}
if (m_pScepConnection)
{
delete m_pScepConnection;
}
if (m_hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
}
if (m_pszPathPlusFileName)
{
FreeMemory(m_pszPathPlusFileName);
}
// Tell the system that it can go to sleep now if it wants
// to...
if (m_dwKind != PACKET_KIND_LISTEN)
{
#ifdef USE_WINNT_CALLS
SetThreadExecutionState( m_ExecutionState );
#else
#pragma message("Missing important call SetThreadExecutionState on Windows9x ")
#endif
}
}
//------------------------------------------------------------------------
// CCONNECTION::operator new()
//
//------------------------------------------------------------------------
void *CCONNECTION::operator new( IN size_t Size )
{
void *pObj = AllocateMemory(Size);
return pObj;
}
//------------------------------------------------------------------------
// CCONNECTION::operator delete()
//
//------------------------------------------------------------------------
void CCONNECTION::operator delete( IN void *pObj,
IN size_t Size )
{
if (pObj)
{
DWORD dwStatus = FreeMemory(pObj);
}
}
//------------------------------------------------------------------------
// CCONNECTION::InitializeForListen()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::InitializeForListen( IN char *pszServiceName,
IN BOOL fIsIrCOMM,
IN HANDLE hIoCP )
{
DWORD dwStatus = NO_ERROR;
SOCKADDR_IRDA AddrLocal;
BYTE bIASSetBuffer[sizeof(IAS_SET) - 3 + IAS_SET_ATTRIB_MAX_LEN];
int iIASSetSize = sizeof(bIASSetBuffer);
IAS_SET *pIASSet = (IAS_SET*)bIASSetBuffer;
int iEnable9WireMode = 1;
// Connections are initialized in listen mode:
SetKind(PACKET_KIND_LISTEN);
// Save the service name for listen sockets:
m_pszServiceName = (char*)AllocateMemory(1+strlen(pszServiceName));
if (m_pszServiceName)
{
strcpy(m_pszServiceName,pszServiceName);
}
// Create a socket that we will listen on:
m_ListenSocket = socket(AF_IRDA,SOCK_STREAM,IPPROTO_IP);
if (m_ListenSocket == INVALID_SOCKET)
{
dwStatus = WSAGetLastError();
#ifdef DBG_ERROR
WIAS_ERROR((g_hInst,"InitializeForListen(%s): socket() Failed: %d\n",pszServiceName,dwStatus));
#endif
return dwStatus;
}
// If this is IrCOMM, the we need to do a little extra work.
if (fIsIrCOMM)
{
// Fill in the 9-wire attributes:
memset(pIASSet,0,iIASSetSize);
memcpy(pIASSet->irdaClassName,IRCOMM_9WIRE,sizeof(IRCOMM_9WIRE));
memcpy(pIASSet->irdaAttribName,IRDA_PARAMETERS,sizeof(IRDA_PARAMETERS));
pIASSet->irdaAttribType = IAS_ATTRIB_OCTETSEQ;
pIASSet->irdaAttribute.irdaAttribOctetSeq.Len = OCTET_SEQ_SIZE;
memcpy(pIASSet->irdaAttribute.irdaAttribOctetSeq.OctetSeq,OCTET_SEQ,OCTET_SEQ_SIZE);
// Add IrCOMM IAS attributes for 3-wire cooked and 9-wire
// raw modes (see the IrCOMM spec)...
if (SOCKET_ERROR == setsockopt(m_ListenSocket,
SOL_IRLMP,
IRLMP_IAS_SET,
(const char*)pIASSet,
iIASSetSize))
{
dwStatus = WSAGetLastError();
#ifdef DBG_ERROR
WIAS_TRACE((g_hInst,"InitializeForListen(%s): setsockopt(IRLMP_IAS_SET) Failed: %d",pszServiceName,dwStatus));
#endif
closesocket(m_ListenSocket);
m_ListenSocket = INVALID_SOCKET;
return dwStatus;
}
// Need to enable 9-wire mode before the bind():
if (SOCKET_ERROR == setsockopt(m_ListenSocket,
SOL_IRLMP,
IRLMP_9WIRE_MODE,
(const char*)&iEnable9WireMode,
sizeof(iEnable9WireMode)))
{
dwStatus = WSAGetLastError();
#ifdef DBG_ERROR
WIAS_TRACE((g_hInst,"InitializeForListen(%s): setsockopt(IRLMP_9WIRE_MODE) Failed: %d",pszServiceName,dwStatus));
#endif
closesocket(m_ListenSocket);
m_ListenSocket = INVALID_SOCKET;
return dwStatus;
}
}
// Setup the local address for the bind():
memset(&AddrLocal,0,sizeof(AddrLocal));
AddrLocal.irdaAddressFamily = AF_IRDA;
strcpy(AddrLocal.irdaServiceName,pszServiceName);
// Note: AddrLocal.irdaDeviceID ignored by server applications...
if (SOCKET_ERROR == bind( m_ListenSocket,
(struct sockaddr *)&AddrLocal,
sizeof(AddrLocal)) )
{
dwStatus = WSAGetLastError();
closesocket(m_ListenSocket);
m_ListenSocket = INVALID_SOCKET;
return dwStatus;
}
if (SOCKET_ERROR == listen(m_ListenSocket,2))
{
dwStatus = WSAGetLastError();
closesocket(m_ListenSocket);
m_ListenSocket = INVALID_SOCKET;
return dwStatus;
}
#ifdef USE_IOCOMPLETION
//
// If this is NT, then associate the listen socket with
// an IO completion port (not supported in Windows98).
//
hIoCP = CreateIoCompletionPort( (void*)m_ListenSocket,
hIoCP,
m_ListenSocket,
0 );
m_hIoCompletionPort = hIoCP;
#endif
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::PostMoreIos()
//
//------------------------------------------------------------------------
#if FALSE
DWORD CCONNECTION::PostMoreIos( CIOPACKET *pIoPacket )
{
DWORD dwStatus = S_OK;
LONG lNumPendingReads;
while (m_lPendingReads < m_lMaxPendingReads)
{
if (!pIoPacket)
{
pIoPacket = new CIOPACKET;
if (!pIoPacket)
{
WIAS_ERROR((g_hInst,"new CIOPACKET failed."));
dwStatus = ERROR_OUTOFMEMORY;
break;
}
dwStatus = pIoPacket->Initialize( GetKind(),
GetListenSocket(),
GetSocket(),
GetIoCompletionPort() );
}
dwStatus = pIoPacket->PostIo();
if (dwStatus != NO_ERROR)
{
WIAS_ERROR((g_hInst,"pNewIoPacket->PostIo() failed: %d\n", dwStatus ));
delete pIoPacket;
break;
}
// Increment the count of the number of pending reads on
// this connection:
lNumPendingReads = IncrementPendingReads();
WIAS_ASSERT(g_hInst,lNumPendingReads > 0);
pIoPacket = 0; // don't delete this line... this is a loop...
}
return dwStatus;
}
#endif
//------------------------------------------------------------------------
// CCONNECTION::SendPdu()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::SendPdu( IN SCEP_HEADER *pPdu,
IN DWORD dwPduSize,
OUT CIOPACKET **ppIoPacket )
{
DWORD dwStatus = NO_ERROR;
CIOPACKET *pIoPacket = new CIOPACKET;
*ppIoPacket = 0;
if (!pIoPacket)
{
return ERROR_OUTOFMEMORY;
}
dwStatus = pIoPacket->Initialize( PACKET_KIND_WRITE_SOCKET,
INVALID_SOCKET, // ListenSocket
GetSocket(),
GetIoCompletionPort() );
if (dwStatus != NO_ERROR)
{
delete pIoPacket;
return dwStatus;
}
dwStatus = pIoPacket->PostIoWrite(pPdu,dwPduSize,0);
delete pIoPacket;
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::ShutdownSocket()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::ShutdownSocket()
{
this->CloseSocket();
return NO_ERROR;
}
//------------------------------------------------------------------------
// CCONNECTION::CloseSocket()
//
//------------------------------------------------------------------------
void CCONNECTION::CloseSocket()
{
if (m_Socket != INVALID_SOCKET)
{
closesocket(m_Socket);
m_Socket = INVALID_SOCKET;
}
}
//------------------------------------------------------------------------
// CCONNECTION::CloseListenSocket()
//
//------------------------------------------------------------------------
void CCONNECTION::CloseListenSocket()
{
if (m_ListenSocket != INVALID_SOCKET)
{
closesocket(m_ListenSocket);
m_ListenSocket = INVALID_SOCKET;
}
}
//------------------------------------------------------------------------
// CCONNECTION::CleanupDateString()
//
// Make sure that the specified date string doesn't contain any slashes
// which could be confused as subdirectories if the date is used as part
// of a path.
//------------------------------------------------------------------------
void CCONNECTION::CleanupDateString( IN OUT CHAR *pszDateStr )
{
if (pszDateStr)
{
while (*pszDateStr)
{
if ((*pszDateStr == '/') || (*pszDateStr == '\\'))
{
*pszDateStr = '-';
}
else if (*pszDateStr < 30)
{
*pszDateStr = '_';
}
pszDateStr++;
}
}
}
//------------------------------------------------------------------------
// CCONNECTION::ConstructPicturesSubDirectory()
//
// Generate the path for the directory where pictures will be stored
// in.
//
// The return path string should be free'd using FreeMemory().
//------------------------------------------------------------------------
char *CCONNECTION::ConstructPicturesSubDirectory( IN DWORD dwExtraChars )
{
char *pszTempDirectory = 0;
char *psz = ::GetImageDirectory();
if (psz)
{
pszTempDirectory = (char*)AllocateMemory( strlen(psz)
+ dwExtraChars
+ 2 );
}
if (pszTempDirectory)
{
strcpy(pszTempDirectory,psz);
}
// Don't try to free psz !!.
return pszTempDirectory;
}
//------------------------------------------------------------------------
// CCONNECTION::ConstructFullFileName()
//
// Generate the path + file name that the picture will be stored
// in. If dwCopyCount is zero, then its just a straight file name.
// If dwCopyCount is N, then "N_" is prefixed to the file name.
//------------------------------------------------------------------------
CHAR *CCONNECTION::ConstructFullFileName( IN DWORD dwCopyCount )
{
# define MAX_DATE 64
# define MAX_PREFIX 64
DWORD dwLen;
DWORD dwFileNameLen;
DWORD dwPrefixStrLen;
DWORD dwExtraChars;
CHAR *pszFullFileName = 0; // Path + file name.
CHAR *pszFileName = 0; // File name only.
CHAR szPrefixStr[MAX_PREFIX];
if (!m_pScepConnection)
{
return 0;
}
pszFileName = m_pScepConnection->GetFileName();
if (!pszFileName)
{
return 0;
}
dwFileNameLen = strlen(pszFileName);
if (dwCopyCount == 0)
{
dwExtraChars = 1 + dwFileNameLen; // Extra 1 for the "\".
}
else
{
_itoa(dwCopyCount,szPrefixStr,10);
strcat(szPrefixStr,SZ_UNDERSCORE);
dwPrefixStrLen = strlen(szPrefixStr);
dwExtraChars = 1 + dwFileNameLen + dwPrefixStrLen;
}
pszFullFileName = CCONNECTION::ConstructPicturesSubDirectory(dwExtraChars);
if (!pszFullFileName)
{
return 0;
}
if (dwCopyCount == 0)
{
strcat(pszFullFileName,SZ_SLASH);
strcat(pszFullFileName,pszFileName);
}
else
{
strcat(pszFullFileName,SZ_SLASH);
strcat(pszFullFileName,szPrefixStr);
strcat(pszFullFileName,pszFileName);
}
#ifdef DBG_IO
WIAS_TRACE((g_hInst,"CCONNECTION::ConstructFullFileName(): return: %s",pszFullFileName));
#endif
return pszFullFileName;
}
//------------------------------------------------------------------------
// CCONNECTION::Impersonate()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::Impersonate()
{
DWORD dwStatus = NO_ERROR;
HANDLE hToken = ::GetUserToken();
if (hToken)
{
if (!ImpersonateLoggedOnUser(hToken))
{
dwStatus = GetLastError();
#ifdef DBG_ERROR
WIAS_ERROR((g_hInst,"IrXfer: IrTran-P: CreatePictureFile(): Impersonate Failed: %d\n",dwStatus));
#endif
}
else
{
m_fImpersonating = TRUE;
#ifdef DBG_IMPERSONATE
WIAS_ERROR((g_hInst,"CCONNECTION::Impersonate(): Impersonate\n"));
#endif
}
}
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::RevertToSelf()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::RevertToSelf()
{
DWORD dwStatus = NO_ERROR;
HANDLE hToken = ::GetUserToken();
if ((hToken) && (m_fImpersonating))
{
::RevertToSelf();
m_fImpersonating = FALSE;
}
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::CreatePictureFile()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::CreatePictureFile()
{
DWORD dwStatus = NO_ERROR;
CHAR *pszFile;
CHAR *pszPathPlusFileName = 0;
DWORD dwFlags = FILE_ATTRIBUTE_NORMAL;
// Make sure that the counters start at zero:
m_dwUpfBytes = 0;
m_dwBytesWritten = 0;
// See if we already have an image file open, if yes then
// close it.
if (m_hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
}
// Get the full path + name for the file we will create.
// Note, that ConstructFullFileName() may create a subdirectory,
// so it needs to be done after the impersonation...
// This is important if we have a remoted \My Documents\
// directory.
DWORD dwCopyCount;
for (dwCopyCount=0; dwCopyCount<=MAX_COPYOF_TRIES; dwCopyCount++)
{
pszPathPlusFileName = ConstructFullFileName(dwCopyCount);
if (!pszPathPlusFileName)
{
return ERROR_SCEP_CANT_CREATE_FILE;
}
//
// Try to create new image (JPEG) file:
//
m_hFile = CreateFile( pszPathPlusFileName,
GENERIC_WRITE,
FILE_SHARE_READ, // Share mode.
0, // Security attr (BUGBUG).
CREATE_NEW, // Open mode.
dwFlags, // Attributes.
0 ); // Template file (none).
if (m_hFile != INVALID_HANDLE_VALUE)
{
// This is the success exit point.
m_pszPathPlusFileName = pszPathPlusFileName;
break;
}
else
{
dwStatus = GetLastError();
if (dwStatus != ERROR_FILE_EXISTS)
{
#ifdef DBG_TARGET_DIR
WIAS_ERROR((g_hInst,"CCONNECTION::CreatePictureFile(): CreateFile(): %s Failed: %d",pszPathPlusFileName,dwStatus));
#endif
FreeMemory(pszPathPlusFileName);
break;
}
// If we get here, then then a picture file by that name
// alreay exists, so try again...
FreeMemory(pszPathPlusFileName);
}
}
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::SetPictureFileTime()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::SetPictureFileTime( IN FILETIME *pFileTime )
{
DWORD dwStatus = NO_ERROR;
if (!pFileTime)
{
return dwStatus; // Empty case, no time to set.
}
if (!SetFileTime(m_hFile,pFileTime,pFileTime,pFileTime))
{
dwStatus = GetLastError();
WIAS_ERROR((g_hInst,"IrTranP: SetFileTime() Failed: %d",dwStatus));
}
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::WritePictureFile()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::WritePictureFile( IN UCHAR *pBuffer,
IN DWORD dwBufferSize,
OUT CIOPACKET **ppIoPacket )
{
DWORD dwStatus = NO_ERROR;
DWORD dwOffset = m_dwBytesWritten;
DWORD dwBytesToWrite;
LONG lPendingWrites;
*ppIoPacket = 0;
CIOPACKET *pIoPacket = new CIOPACKET;
if (!pIoPacket)
{
return ERROR_OUTOFMEMORY;
}
dwStatus = pIoPacket->Initialize( PACKET_KIND_WRITE_FILE,
INVALID_SOCKET, // ListenSocket
INVALID_SOCKET, // Camera...
GetIoCompletionPort() );
if (dwStatus != NO_ERROR)
{
delete pIoPacket;
return dwStatus;
}
pIoPacket->SetFileHandle(m_hFile);
//
// If we are writing just the JPEG image out of the UPF file,
// then we don't want to write the first m_dwJpegOffset bytes
// of the UPF file.
//
if ((m_dwUpfBytes >= m_dwJpegOffset) || (m_fSaveAsUPF))
{
dwBytesToWrite = dwBufferSize;
}
else if ((m_dwUpfBytes + dwBufferSize) > m_dwJpegOffset)
{
dwBytesToWrite = (m_dwUpfBytes + dwBufferSize) - m_dwJpegOffset;
for (DWORD i=0; i<dwBytesToWrite; i++)
{
pBuffer[i] = pBuffer[i+m_dwJpegOffset-m_dwUpfBytes];
}
}
else
{
dwBytesToWrite = 0;
}
//
// When we start writing the JPEG file we want to cut off the
// file save writes once we've written out the m_dwJpegSize
// bytes that are the JPEG image inside of the UPF file.
//
if (!m_fSaveAsUPF)
{
if (m_dwBytesWritten < m_dwJpegSize)
{
if ((m_dwBytesWritten+dwBytesToWrite) > m_dwJpegSize)
{
dwBytesToWrite = m_dwJpegSize - m_dwBytesWritten;
}
}
else
{
dwBytesToWrite = 0;
}
}
//
// If there are bytes to actually write, then let's do it.
//
if (dwBytesToWrite > 0)
{
dwStatus = pIoPacket->PostIoWrite(pBuffer,dwBytesToWrite,dwOffset);
if (dwStatus == NO_ERROR)
{
lPendingWrites = IncrementPendingWrites();
WIAS_ASSERT(g_hInst, lPendingWrites > 0 );
m_dwBytesWritten += dwBytesToWrite;
*ppIoPacket = pIoPacket;
}
}
delete pIoPacket;
m_dwUpfBytes += dwBufferSize;
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::DeletePictureFile()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::DeletePictureFile()
{
DWORD dwStatus = NO_ERROR;
if (m_hFile == INVALID_HANDLE_VALUE)
{
return NO_ERROR;
}
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
if (m_pszPathPlusFileName)
{
DeleteFile(m_pszPathPlusFileName);
}
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::ClosePictureFile()
//
//------------------------------------------------------------------------
DWORD CCONNECTION::ClosePictureFile()
{
DWORD dwStatus = NO_ERROR;
#if FALSE
if (m_pszPathPlusFileName)
{
FreeMemory(m_pszPathPlusFileName);
m_pszPathPlusFileName = 0;
}
#endif
if (m_hFile != INVALID_HANDLE_VALUE)
{
if (!CloseHandle(m_hFile))
{
dwStatus = GetLastError();
}
m_hFile = INVALID_HANDLE_VALUE;
}
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::IncompleteFile()
//
// Check to see if we have a complete picture file, if yes, then return
// FALSE, else return TRUE.
//------------------------------------------------------------------------
BOOL CCONNECTION::IncompleteFile()
{
BOOL fIncomplete = FALSE;
if (m_fSaveAsUPF)
{
// Note: currently save the .UPF file, even if its incomplete.
// This file mode is set in the registry and is for testing
// only...
fIncomplete = FALSE;
}
else if (!m_fReceiveComplete)
{
fIncomplete = (m_dwBytesWritten < m_dwJpegSize);
}
return fIncomplete;
}
//------------------------------------------------------------------------
// CCONNECTION::StartProgress()
//
// Startup the progress bar for the incomming JPEG.
//------------------------------------------------------------------------
DWORD CCONNECTION::StartProgress()
{
DWORD dwStatus = 0;
if (!m_pIrProgress)
{
m_pIrProgress = new CIrProgress;
if (m_pIrProgress)
{
dwStatus = m_pIrProgress->Initialize(g_hInst,IDR_TRANSFER_AVI);
}
else
{
return E_OUTOFMEMORY;
}
}
if (m_pIrProgress)
{
dwStatus = m_pIrProgress->StartProgressDialog();
}
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::UpdateProgress()
//
// Update the progress bar's completion display.
//------------------------------------------------------------------------
DWORD CCONNECTION::UpdateProgress()
{
DWORD dwStatus = 0;
if (m_pIrProgress)
{
dwStatus = m_pIrProgress->UpdateProgressDialog( m_dwBytesWritten,
m_dwJpegSize );
}
return dwStatus;
}
//------------------------------------------------------------------------
// CCONNECTION::EndProgress()
//
// File transfer complete, hide the progress bar.
//------------------------------------------------------------------------
DWORD CCONNECTION::EndProgress()
{
DWORD dwStatus = 0;
if (m_pIrProgress)
{
dwStatus = m_pIrProgress->EndProgressDialog();
delete m_pIrProgress;
m_pIrProgress = NULL;
}
return dwStatus;
}
//************************************************************************
//------------------------------------------------------------------------
// CCONNECTION_MAP::CCONNECTION_MAP()
//
//------------------------------------------------------------------------
CCONNECTION_MAP::CCONNECTION_MAP()
{
m_dwMapSize = 0;
m_pMap = 0;
ZeroMemory(&m_cs, sizeof(m_cs));
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::~CCONNECTION_MAP()
//
//------------------------------------------------------------------------
CCONNECTION_MAP::~CCONNECTION_MAP()
{
if (m_pMap)
{
DeleteCriticalSection(&m_cs);
FreeMemory(m_pMap);
}
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::operator new()
//
//------------------------------------------------------------------------
void *CCONNECTION_MAP::operator new( IN size_t Size )
{
void *pObj = AllocateMemory(Size);
return pObj;
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::operator delete()
//
//------------------------------------------------------------------------
void CCONNECTION_MAP::operator delete( IN void *pObj,
IN size_t Size )
{
if (pObj)
{
DWORD dwStatus = FreeMemory(pObj);
}
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::Initialize()
//
//------------------------------------------------------------------------
BOOL CCONNECTION_MAP::Initialize( IN DWORD dwNewMapSize )
{
if (!dwNewMapSize)
{
return FALSE;
}
if (!m_dwMapSize)
{
m_pMap = (CONNECTION_MAP_ENTRY*)AllocateMemory( dwNewMapSize*sizeof(CONNECTION_MAP_ENTRY) );
if (!m_pMap)
{
return FALSE;
}
__try
{
if(!InitializeCriticalSectionAndSpinCount(&m_cs, MINLONG))
{
FreeMemory(m_pMap);
m_pMap = NULL;
return FALSE;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
FreeMemory(m_pMap);
m_pMap = NULL;
return FALSE;
}
m_dwMapSize = dwNewMapSize;
memset(m_pMap,0,m_dwMapSize*sizeof(CONNECTION_MAP_ENTRY));
for (DWORD i=0; i<m_dwMapSize; i++)
{
m_pMap[i].Socket = INVALID_SOCKET;
}
}
return TRUE;
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::Lookup()
//
//------------------------------------------------------------------------
CCONNECTION *CCONNECTION_MAP::Lookup( IN SOCKET Socket )
{
DWORD i;
EnterCriticalSection(&m_cs);
for (i=0; i<m_dwMapSize; i++)
{
if (m_pMap[i].Socket == Socket)
{
LeaveCriticalSection(&m_cs);
return m_pMap[i].pConnection;
}
}
LeaveCriticalSection(&m_cs);
return 0;
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::LookupByServiceName()
//
//------------------------------------------------------------------------
CCONNECTION *CCONNECTION_MAP::LookupByServiceName( IN char *pszServiceName )
{
DWORD i;
CCONNECTION *pConnection;
EnterCriticalSection(&m_cs);
for (i=0; i<m_dwMapSize; i++)
{
pConnection = m_pMap[i].pConnection;
if ( (pConnection)
&& (pConnection->GetServiceName())
&& (!strcmp(pConnection->GetServiceName(),pszServiceName)))
{
LeaveCriticalSection(&m_cs);
return pConnection;
}
}
LeaveCriticalSection(&m_cs);
return 0;
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::Add()
//
//------------------------------------------------------------------------
BOOL CCONNECTION_MAP::Add( IN CCONNECTION *pConnection,
IN SOCKET Socket )
{
DWORD i;
// Only add entries that look valid...
if ((Socket == 0)||(Socket==INVALID_SOCKET)||(pConnection == 0))
{
return FALSE;
}
EnterCriticalSection(&m_cs);
// Look for an empty place in the table:
for (i=0; i<m_dwMapSize; i++)
{
if (m_pMap[i].Socket == INVALID_SOCKET)
{
m_pMap[i].Socket = Socket;
m_pMap[i].pConnection = pConnection;
LeaveCriticalSection(&m_cs);
return TRUE;
}
}
// The table is full, expand it...
DWORD dwNewMapSize = 3*m_dwMapSize/2; // 50% bigger.
CONNECTION_MAP_ENTRY *pMap = (CONNECTION_MAP_ENTRY*)AllocateMemory( dwNewMapSize*sizeof(CONNECTION_MAP_ENTRY) );
if (!pMap)
{
LeaveCriticalSection(&m_cs);
return FALSE; // Out of memory...
}
memset(pMap,0,dwNewMapSize*sizeof(CONNECTION_MAP_ENTRY));
for (i=0; i<dwNewMapSize; i++)
{
pMap[i].Socket = INVALID_SOCKET;
}
for (i=0; i<m_dwMapSize; i++)
{
pMap[i].Socket = m_pMap[i].Socket;
pMap[i].pConnection = m_pMap[i].pConnection;
}
pMap[i].Socket = Socket;
pMap[i].pConnection = pConnection;
FreeMemory(m_pMap);
m_pMap = pMap;
m_dwMapSize = dwNewMapSize;
LeaveCriticalSection(&m_cs);
return TRUE;
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::Remove()
//
//------------------------------------------------------------------------
CCONNECTION *CCONNECTION_MAP::Remove( IN SOCKET Socket )
{
DWORD i;
CCONNECTION *pConnection;
EnterCriticalSection(&m_cs);
for (i=0; i<m_dwMapSize; i++)
{
if (m_pMap[i].Socket == Socket)
{
pConnection = m_pMap[i].pConnection;
m_pMap[i].Socket = INVALID_SOCKET;
m_pMap[i].pConnection = 0;
LeaveCriticalSection(&m_cs);
return pConnection;
}
}
LeaveCriticalSection(&m_cs);
return 0;
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::RemoveConnection()
//
//------------------------------------------------------------------------
CCONNECTION *CCONNECTION_MAP::RemoveConnection( IN CCONNECTION *pConnection )
{
DWORD i;
EnterCriticalSection(&m_cs);
for (i=0; i<m_dwMapSize; i++)
{
if (m_pMap[i].pConnection == pConnection)
{
m_pMap[i].Socket = INVALID_SOCKET;
m_pMap[i].pConnection = 0;
LeaveCriticalSection(&m_cs);
return pConnection;
}
}
LeaveCriticalSection(&m_cs);
return 0;
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::RemoveNext()
//
// Walk through the connection map and get the next entry, remove the
// entry from the map as well.
//------------------------------------------------------------------------
CCONNECTION *CCONNECTION_MAP::RemoveNext()
{
DWORD i;
CCONNECTION *pConnection;
EnterCriticalSection(&m_cs);
for (i=0; i<m_dwMapSize; i++)
{
if (m_pMap[i].Socket)
{
pConnection = m_pMap[i].pConnection;
m_pMap[i].Socket = INVALID_SOCKET;
m_pMap[i].pConnection = 0;
LeaveCriticalSection(&m_cs);
return pConnection;
}
}
LeaveCriticalSection(&m_cs);
return 0;
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::ReturnNext()
//
// Walk through the connection map returning the next entry. To start at
// the "begining", pass in state equal zero. When you get to the end of
// the list of connections, return NULL;
//------------------------------------------------------------------------
CCONNECTION *CCONNECTION_MAP::ReturnNext( IN OUT DWORD *pdwState )
{
CCONNECTION *pConnection = NULL;
EnterCriticalSection(&m_cs);
if (*pdwState >= m_dwMapSize)
{
LeaveCriticalSection(&m_cs);
return NULL;
}
while ((pConnection == NULL) && (*pdwState < m_dwMapSize))
{
pConnection = m_pMap[(*pdwState)++].pConnection;
}
LeaveCriticalSection(&m_cs);
return pConnection;
}
//------------------------------------------------------------------------
// CCONNECTION_MAP::ReturnNextSocket()
//
// Walk through the connection map returning the SOCKET associated with
// the next entry. To start at the "begining", pass in state equal zero.
// When you get to the end of the list of connections, return
// INVALID_SOCKET.
//------------------------------------------------------------------------
SOCKET CCONNECTION_MAP::ReturnNextSocket( IN OUT DWORD *pdwState )
{
SOCKET Socket = INVALID_SOCKET;
EnterCriticalSection(&m_cs);
if (*pdwState >= m_dwMapSize)
{
LeaveCriticalSection(&m_cs);
return INVALID_SOCKET;
}
while ((Socket == INVALID_SOCKET) && (*pdwState < m_dwMapSize))
{
Socket = m_pMap[(*pdwState)++].Socket;
}
LeaveCriticalSection(&m_cs);
return Socket;
}