644 lines
22 KiB
C++
644 lines
22 KiB
C++
/***************************************************************************
|
|
*
|
|
* Copyright (C) 2001-2002 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: upnpdevice.h
|
|
*
|
|
* Content: Header for UPnP device object class.
|
|
*
|
|
* History:
|
|
* Date By Reason
|
|
* ======== ======== =========
|
|
* 02/10/01 VanceO Created.
|
|
*
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Defines
|
|
//=============================================================================
|
|
#define MAX_RECEIVE_BUFFER_SIZE (100 * 1024) // 100 K, must be greater than UPNP_STREAM_RECV_BUFFER_INITIAL_SIZE
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Object flags
|
|
//=============================================================================
|
|
#define UPNPDEVICE_WANPPPCONNECTION 0x01 // flag set if the device is a WANPPPConnection device, not set if it is a WANIPConnection device
|
|
#define UPNPDEVICE_CONNECTING 0x02 // flag set while the TCP connection is in progress
|
|
#define UPNPDEVICE_CONNECTED 0x04 // flag set once the TCP connection has been established
|
|
#define UPNPDEVICE_READY 0x08 // flag set once the device is capable of being used
|
|
#define UPNPDEVICE_WAITINGFORCONTROLRESPONSE 0x10 // flag set if some function is waiting for a control response
|
|
#define UPNPDEVICE_DOESNOTSUPPORTASYMMETRICMAPPINGS 0x20 // flag set when the device has indicated it does not support asymmetric mappings
|
|
#define UPNPDEVICE_DOESNOTSUPPORTLEASEDURATIONS 0x40 // flag set when the device has indicated it does not support non-INFINITE lease durations
|
|
#define UPNPDEVICE_USINGCHUNKEDTRANSFERENCODING 0x80 // flag set when device is sending current response using chunked transfer encoding
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Macros
|
|
//=============================================================================
|
|
#define UPNPDEVICE_FROM_BILINK(b) (CONTAINING_OBJECT(b, CUPnPDevice, m_blList))
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Enums
|
|
//=============================================================================
|
|
|
|
//
|
|
// UPnP expected control response enum
|
|
//
|
|
typedef enum _CONTROLRESPONSETYPE
|
|
{
|
|
CONTROLRESPONSETYPE_NONE, // no handler
|
|
//CONTROLRESPONSETYPE_QUERYSTATEVARIABLE_EXTERNALIPADDRESS, // use the ExternalIPAddress QueryStateVariable handler
|
|
CONTROLRESPONSETYPE_GETEXTERNALIPADDRESS, // use the GetExternalIPAddress handler
|
|
CONTROLRESPONSETYPE_ADDPORTMAPPING, // use the AddPortMapping handler
|
|
CONTROLRESPONSETYPE_GETSPECIFICPORTMAPPINGENTRY, // use the GetSpecificPortMappingEntry handler
|
|
CONTROLRESPONSETYPE_DELETEPORTMAPPING // use the DeletePortMapping handler
|
|
} CONTROLRESPONSETYPE;
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Structures
|
|
//=============================================================================
|
|
typedef struct _UPNP_CONTROLRESPONSE_INFO
|
|
{
|
|
HRESULT hrErrorCode; // error code returned by server
|
|
DWORD dwInternalClientV4; // internal client address returned by server
|
|
WORD wInternalPort; // internal client port returned by server
|
|
DWORD dwExternalIPAddressV4; // external IP address returned by server
|
|
} UPNP_CONTROLRESPONSE_INFO, * PUPNP_CONTROLRESPONSE_INFO;
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// UPnP device object class
|
|
//=============================================================================
|
|
class CUPnPDevice
|
|
{
|
|
public:
|
|
CUPnPDevice(const DWORD dwID)
|
|
{
|
|
this->m_blList.Initialize();
|
|
|
|
this->m_Sig[0] = 'U';
|
|
this->m_Sig[1] = 'P';
|
|
this->m_Sig[2] = 'D';
|
|
this->m_Sig[3] = 'V';
|
|
|
|
this->m_lRefCount = 1; // whoever got a pointer to this has a reference
|
|
this->m_dwFlags = 0;
|
|
this->m_dwID = dwID;
|
|
this->m_pOwningDevice = NULL;
|
|
this->m_pszLocationURL = NULL;
|
|
ZeroMemory(&this->m_saddrinHost, sizeof(this->m_saddrinHost));
|
|
ZeroMemory(&this->m_saddrinControl, sizeof(this->m_saddrinControl));
|
|
this->m_pszUSN = NULL;
|
|
this->m_pszServiceControlURL = NULL;
|
|
this->m_sControl = INVALID_SOCKET;
|
|
this->m_pcReceiveBuffer = NULL;
|
|
this->m_dwReceiveBufferSize = 0;
|
|
this->m_pcReceiveBufferStart = NULL;
|
|
this->m_dwUsedReceiveBufferSize = 0;
|
|
this->m_dwRemainingReceiveBufferSize = 0;
|
|
this->m_dwExternalIPAddressV4 = 0;
|
|
this->m_blCachedMaps.Initialize();
|
|
|
|
this->m_dwExpectedContentLength = 0;
|
|
this->m_dwHTTPResponseCode = 0;
|
|
|
|
this->m_ControlResponseType = CONTROLRESPONSETYPE_NONE;
|
|
this->m_pControlResponseInfo = NULL;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::~CUPnPDevice"
|
|
~CUPnPDevice(void)
|
|
{
|
|
DNASSERT(this->m_blList.IsEmpty());
|
|
|
|
DNASSERT(this->m_lRefCount == 0);
|
|
DNASSERT(this->m_pOwningDevice == NULL);
|
|
DNASSERT(this->m_pszLocationURL == NULL);
|
|
DNASSERT(this->m_pszUSN == NULL);
|
|
DNASSERT(this->m_pszServiceControlURL == NULL);
|
|
DNASSERT(this->m_sControl == INVALID_SOCKET);
|
|
DNASSERT(this->m_pcReceiveBuffer == NULL);
|
|
DNASSERT(this->m_blCachedMaps.IsEmpty());
|
|
|
|
DNASSERT(this->m_ControlResponseType == CONTROLRESPONSETYPE_NONE);
|
|
DNASSERT(this->m_pControlResponseInfo == NULL);
|
|
};
|
|
|
|
inline void AddRef(void) { this->m_lRefCount++; };
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::DecRef"
|
|
inline void DecRef(void)
|
|
{
|
|
this->m_lRefCount--;
|
|
DNASSERT(this->m_lRefCount >= 0);
|
|
if (this->m_lRefCount == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
};
|
|
|
|
|
|
inline BOOL IsWANPPPConnection(void) const { return ((this->m_dwFlags & UPNPDEVICE_WANPPPCONNECTION) ? TRUE : FALSE); };
|
|
inline BOOL IsConnecting(void) const { return ((this->m_dwFlags & UPNPDEVICE_CONNECTING) ? TRUE : FALSE); };
|
|
inline BOOL IsConnected(void) const { return ((this->m_dwFlags & UPNPDEVICE_CONNECTED) ? TRUE : FALSE); };
|
|
inline BOOL IsReady(void) const { return ((this->m_dwFlags & UPNPDEVICE_READY) ? TRUE : FALSE); };
|
|
inline BOOL DoesNotSupportAsymmetricMappings(void) const { return ((this->m_dwFlags & UPNPDEVICE_DOESNOTSUPPORTASYMMETRICMAPPINGS) ? TRUE : FALSE); };
|
|
inline BOOL DoesNotSupportLeaseDurations(void) const { return ((this->m_dwFlags & UPNPDEVICE_DOESNOTSUPPORTLEASEDURATIONS) ? TRUE : FALSE); };
|
|
inline BOOL IsUsingChunkedTransferEncoding(void) const { return ((this->m_dwFlags & UPNPDEVICE_USINGCHUNKEDTRANSFERENCODING) ? TRUE : FALSE); };
|
|
|
|
inline DWORD GetID(void) const { return this->m_dwID; };
|
|
inline const char * GetStaticServiceURI(void) const { return ((this->m_dwFlags & UPNPDEVICE_WANPPPCONNECTION) ? URI_SERVICE_WANPPPCONNECTION_A : URI_SERVICE_WANIPCONNECTION_A); };
|
|
inline int GetStaticServiceURILength(void) const { return ((this->m_dwFlags & UPNPDEVICE_WANPPPCONNECTION) ? strlen(URI_SERVICE_WANPPPCONNECTION_A) : strlen(URI_SERVICE_WANIPCONNECTION_A)); };
|
|
inline SOCKADDR_IN * GetHostAddress(void) { return &this->m_saddrinHost; };
|
|
inline SOCKADDR_IN * GetControlAddress(void) { return &this->m_saddrinControl; };
|
|
|
|
inline SOCKET GetControlSocket(void) const { return this->m_sControl; };
|
|
|
|
inline DWORD GetExternalIPAddressV4(void) const { return this->m_dwExternalIPAddressV4; };
|
|
|
|
inline CBilink * GetCachedMaps(void) { return &this->m_blCachedMaps; };
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteWANPPPConnection"
|
|
inline void NoteWANPPPConnection(void)
|
|
{
|
|
DNASSERT(! (this->m_dwFlags & UPNPDEVICE_WANPPPCONNECTION));
|
|
this->m_dwFlags |= UPNPDEVICE_WANPPPCONNECTION;
|
|
};
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteConnecting"
|
|
inline void NoteConnecting(void)
|
|
{
|
|
DNASSERT(! (this->m_dwFlags & (UPNPDEVICE_CONNECTING | UPNPDEVICE_CONNECTED)));
|
|
this->m_dwFlags |= UPNPDEVICE_CONNECTING;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteConnected"
|
|
inline void NoteConnected(void)
|
|
{
|
|
DNASSERT(this->m_dwFlags & UPNPDEVICE_CONNECTING);
|
|
DNASSERT(! (this->m_dwFlags & UPNPDEVICE_CONNECTED));
|
|
this->m_dwFlags &= ~UPNPDEVICE_CONNECTING;
|
|
this->m_dwFlags |= UPNPDEVICE_CONNECTED;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteNotConnected"
|
|
inline void NoteNotConnected(void)
|
|
{
|
|
DNASSERT(this->m_dwFlags & UPNPDEVICE_CONNECTED);
|
|
this->m_dwFlags &= ~UPNPDEVICE_CONNECTED;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteReady"
|
|
inline void NoteReady(void)
|
|
{
|
|
DNASSERT(! (this->m_dwFlags & UPNPDEVICE_READY));
|
|
this->m_dwFlags |= UPNPDEVICE_READY;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteDoesNotSupportAsymmetricMappings"
|
|
inline void NoteDoesNotSupportAsymmetricMappings(void)
|
|
{
|
|
DNASSERT(! (this->m_dwFlags & UPNPDEVICE_DOESNOTSUPPORTASYMMETRICMAPPINGS));
|
|
this->m_dwFlags |= UPNPDEVICE_DOESNOTSUPPORTASYMMETRICMAPPINGS;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteDoesNotSupportLeaseDurations"
|
|
inline void NoteDoesNotSupportLeaseDurations(void)
|
|
{
|
|
DNASSERT(! (this->m_dwFlags & UPNPDEVICE_DOESNOTSUPPORTLEASEDURATIONS));
|
|
this->m_dwFlags |= UPNPDEVICE_DOESNOTSUPPORTLEASEDURATIONS;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteUsingChunkedTransferEncoding"
|
|
inline void NoteUsingChunkedTransferEncoding(void)
|
|
{
|
|
DNASSERT(! (this->m_dwFlags & UPNPDEVICE_USINGCHUNKEDTRANSFERENCODING));
|
|
this->m_dwFlags |= UPNPDEVICE_USINGCHUNKEDTRANSFERENCODING;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteNotUsingChunkedTransferEncoding"
|
|
inline void NoteNotUsingChunkedTransferEncoding(void)
|
|
{
|
|
DNASSERT(this->m_dwFlags & UPNPDEVICE_USINGCHUNKEDTRANSFERENCODING);
|
|
this->m_dwFlags &= ~UPNPDEVICE_USINGCHUNKEDTRANSFERENCODING;
|
|
};
|
|
|
|
|
|
inline void SetHostAddress(SOCKADDR_IN * psaddrinHost)
|
|
{
|
|
CopyMemory(&this->m_saddrinHost, psaddrinHost, sizeof(this->m_saddrinHost));
|
|
};
|
|
|
|
inline void SetControlAddress(SOCKADDR_IN * psaddrinControl)
|
|
{
|
|
CopyMemory(&this->m_saddrinControl, psaddrinControl, sizeof(this->m_saddrinControl));
|
|
};
|
|
|
|
inline BOOL IsLocal(void) const { return ((this->m_saddrinControl.sin_addr.S_un.S_addr == this->m_pOwningDevice->GetLocalAddressV4()) ? TRUE : FALSE); };
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::SetLocationURL"
|
|
inline HRESULT SetLocationURL(const char * const szLocationURL)
|
|
{
|
|
DNASSERT(this->m_pszLocationURL == NULL);
|
|
|
|
this->m_pszLocationURL = (char*) DNMalloc((strlen(szLocationURL) + 1) * sizeof(char));
|
|
if (this->m_pszLocationURL == NULL)
|
|
{
|
|
return DPNHERR_OUTOFMEMORY;
|
|
}
|
|
|
|
strcpy(this->m_pszLocationURL, szLocationURL);
|
|
|
|
return DPNH_OK;
|
|
};
|
|
|
|
inline char * GetLocationURL(void) { return this->m_pszLocationURL; };
|
|
|
|
inline void ClearLocationURL(void)
|
|
{
|
|
if (this->m_pszLocationURL != NULL)
|
|
{
|
|
DNFree(this->m_pszLocationURL);
|
|
this->m_pszLocationURL = NULL;
|
|
}
|
|
};
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::SetUSN"
|
|
inline HRESULT SetUSN(const char * const szUSN)
|
|
{
|
|
DNASSERT(this->m_pszUSN == NULL);
|
|
|
|
this->m_pszUSN = (char*) DNMalloc((strlen(szUSN) + 1) * sizeof(char));
|
|
if (this->m_pszUSN == NULL)
|
|
{
|
|
return DPNHERR_OUTOFMEMORY;
|
|
}
|
|
|
|
strcpy(this->m_pszUSN, szUSN);
|
|
|
|
return DPNH_OK;
|
|
};
|
|
|
|
inline char * GetUSN(void) { return this->m_pszUSN; };
|
|
|
|
inline void ClearUSN(void)
|
|
{
|
|
if (this->m_pszUSN != NULL)
|
|
{
|
|
DNFree(this->m_pszUSN);
|
|
this->m_pszUSN = NULL;
|
|
}
|
|
};
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::SetServiceControlURL"
|
|
inline HRESULT SetServiceControlURL(const char * const szServiceControlURL)
|
|
{
|
|
DNASSERT(this->m_pszServiceControlURL == NULL);
|
|
|
|
this->m_pszServiceControlURL = (char*) DNMalloc((strlen(szServiceControlURL) + 1) * sizeof(char));
|
|
if (this->m_pszServiceControlURL == NULL)
|
|
{
|
|
return DPNHERR_OUTOFMEMORY;
|
|
}
|
|
|
|
strcpy(this->m_pszServiceControlURL, szServiceControlURL);
|
|
|
|
return DPNH_OK;
|
|
};
|
|
|
|
inline char * GetServiceControlURL(void) { return this->m_pszServiceControlURL; };
|
|
|
|
inline void ClearServiceControlURL(void)
|
|
{
|
|
if (this->m_pszServiceControlURL != NULL)
|
|
{
|
|
DNFree(this->m_pszServiceControlURL);
|
|
this->m_pszServiceControlURL = NULL;
|
|
}
|
|
};
|
|
|
|
|
|
inline void SetControlSocket(SOCKET sControl) { this->m_sControl = sControl; };
|
|
|
|
|
|
//
|
|
// You must have global object lock to call this function.
|
|
//
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::MakeDeviceOwner"
|
|
inline void MakeDeviceOwner(CDevice * const pDevice)
|
|
{
|
|
DNASSERT(pDevice != NULL);
|
|
DNASSERT(pDevice->GetUPnPDevice() == NULL);
|
|
DNASSERT(this->m_pOwningDevice == NULL);
|
|
|
|
this->m_pOwningDevice = pDevice;
|
|
|
|
this->AddRef();
|
|
pDevice->SetUPnPDevice(this);
|
|
};
|
|
|
|
|
|
//
|
|
// You must have global object lock to call this function.
|
|
//
|
|
inline CDevice * GetOwningDevice(void) { return this->m_pOwningDevice; };
|
|
|
|
|
|
//
|
|
// You must have global object lock to call this function.
|
|
//
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::ClearDeviceOwner"
|
|
inline void ClearDeviceOwner(void)
|
|
{
|
|
DNASSERT(this->m_pOwningDevice != NULL);
|
|
DNASSERT(this->m_pOwningDevice->GetUPnPDevice() == this);
|
|
|
|
this->m_pOwningDevice->SetUPnPDevice(NULL);
|
|
this->m_pOwningDevice = NULL;
|
|
this->DecRef();
|
|
};
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::CreateReceiveBuffer"
|
|
inline HRESULT CreateReceiveBuffer(const DWORD dwSize)
|
|
{
|
|
DNASSERT(this->m_pcReceiveBuffer == NULL);
|
|
|
|
|
|
this->m_pcReceiveBuffer = (char*) DNMalloc(dwSize);
|
|
if (this->m_pcReceiveBuffer == NULL)
|
|
{
|
|
return DPNHERR_OUTOFMEMORY;
|
|
}
|
|
|
|
this->m_dwReceiveBufferSize = dwSize;
|
|
this->m_pcReceiveBufferStart = this->m_pcReceiveBuffer;
|
|
this->m_dwRemainingReceiveBufferSize = dwSize;
|
|
|
|
return DPNH_OK;
|
|
};
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::IncreaseReceiveBufferSize"
|
|
inline HRESULT IncreaseReceiveBufferSize(void)
|
|
{
|
|
DWORD dwNewBufferSize;
|
|
char * pcTemp;
|
|
|
|
|
|
DNASSERT(this->m_pcReceiveBuffer != NULL);
|
|
|
|
|
|
//
|
|
// Double the buffer size. Don't let the receive buffer get to
|
|
// unrealistic sizes to prevent DoS/resource issues, cap the buffer
|
|
// size, and if we've already reached that limit, fail.
|
|
//
|
|
dwNewBufferSize = this->m_dwReceiveBufferSize * 2;
|
|
if (dwNewBufferSize > MAX_RECEIVE_BUFFER_SIZE)
|
|
{
|
|
dwNewBufferSize = MAX_RECEIVE_BUFFER_SIZE;
|
|
if (dwNewBufferSize <= this->m_dwReceiveBufferSize)
|
|
{
|
|
DPFX(DPFPREP, 0, "Maximum buffer size reached (%u bytes), not allocating more room!",
|
|
this->m_dwReceiveBufferSize);
|
|
return DPNHERR_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
pcTemp = (char*) DNMalloc(dwNewBufferSize);
|
|
if (pcTemp == NULL)
|
|
{
|
|
return DPNHERR_OUTOFMEMORY;
|
|
}
|
|
|
|
//
|
|
// If the buffer already had data in it, copy it. The data may not
|
|
// have come from the front of the old buffer, but it will
|
|
// definitely be the front of the new one.
|
|
//
|
|
if (this->m_dwUsedReceiveBufferSize > 0)
|
|
{
|
|
CopyMemory(pcTemp, this->m_pcReceiveBufferStart,
|
|
this->m_dwUsedReceiveBufferSize);
|
|
}
|
|
|
|
DNFree(this->m_pcReceiveBuffer);
|
|
this->m_pcReceiveBuffer = NULL;
|
|
|
|
|
|
this->m_pcReceiveBuffer = pcTemp;
|
|
this->m_dwReceiveBufferSize = dwNewBufferSize;
|
|
|
|
//
|
|
// The buffer now starts at the beginning of the allocated memory
|
|
// (we may have just freed up a bunch of wasted space).
|
|
//
|
|
this->m_pcReceiveBufferStart = this->m_pcReceiveBuffer;
|
|
this->m_dwRemainingReceiveBufferSize = this->m_dwReceiveBufferSize - this->m_dwUsedReceiveBufferSize;
|
|
|
|
return DPNH_OK;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::UpdateUsedReceiveBufferSize"
|
|
inline void UpdateUsedReceiveBufferSize(const DWORD dwAdditionalSizeUsed)
|
|
{
|
|
DNASSERT(dwAdditionalSizeUsed <= this->m_dwRemainingReceiveBufferSize);
|
|
DNASSERT((this->m_dwUsedReceiveBufferSize + dwAdditionalSizeUsed) <= this->m_dwReceiveBufferSize);
|
|
this->m_dwUsedReceiveBufferSize += dwAdditionalSizeUsed;
|
|
this->m_dwRemainingReceiveBufferSize -= dwAdditionalSizeUsed;
|
|
};
|
|
|
|
inline void ClearReceiveBuffer(void)
|
|
{
|
|
this->m_pcReceiveBufferStart = this->m_pcReceiveBuffer;
|
|
this->m_dwUsedReceiveBufferSize = 0;
|
|
this->m_dwRemainingReceiveBufferSize = this->m_dwReceiveBufferSize;
|
|
};
|
|
|
|
inline char * GetReceiveBufferStart(void) { return this->m_pcReceiveBufferStart; };
|
|
inline char * GetCurrentReceiveBufferPtr(void) { return (this->m_pcReceiveBufferStart + this->m_dwUsedReceiveBufferSize); };
|
|
inline DWORD GetUsedReceiveBufferSize(void) const { return this->m_dwUsedReceiveBufferSize; };
|
|
inline DWORD GetRemainingReceiveBufferSize(void) const { return this->m_dwRemainingReceiveBufferSize; };
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::UpdateReceiveBufferStart"
|
|
inline void UpdateReceiveBufferStart(char * pszNewStart)
|
|
{
|
|
DNASSERT(pszNewStart > this->m_pcReceiveBufferStart);
|
|
DNASSERT((DWORD) ((DWORD_PTR) (pszNewStart - this->m_pcReceiveBufferStart)) < this->m_dwRemainingReceiveBufferSize);
|
|
this->m_dwUsedReceiveBufferSize -= (DWORD) ((DWORD_PTR) (pszNewStart - this->m_pcReceiveBufferStart));
|
|
this->m_pcReceiveBufferStart = pszNewStart;
|
|
};
|
|
|
|
inline void DestroyReceiveBuffer(void)
|
|
{
|
|
if (this->m_pcReceiveBuffer != NULL)
|
|
{
|
|
DNFree(this->m_pcReceiveBuffer);
|
|
this->m_pcReceiveBuffer = NULL;
|
|
this->m_dwReceiveBufferSize = 0;
|
|
this->m_pcReceiveBufferStart = NULL;
|
|
this->m_dwUsedReceiveBufferSize = 0;
|
|
this->m_dwRemainingReceiveBufferSize = 0;
|
|
}
|
|
};
|
|
|
|
|
|
inline void SetExternalIPAddressV4(const DWORD dwExternalIPAddressV4)
|
|
{
|
|
this->m_dwExternalIPAddressV4 = dwExternalIPAddressV4;
|
|
};
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::RemoveAllCachedMappings"
|
|
inline void RemoveAllCachedMappings(void)
|
|
{
|
|
CBilink * pCachedMaps;
|
|
CBilink * pBilink;
|
|
CCacheMap * pCacheMap;
|
|
|
|
|
|
pCachedMaps = this->GetCachedMaps();
|
|
pBilink = pCachedMaps->GetNext();
|
|
while (pBilink != pCachedMaps)
|
|
{
|
|
DNASSERT(! pBilink->IsEmpty());
|
|
|
|
|
|
pCacheMap = CACHEMAP_FROM_BILINK(pBilink);
|
|
pBilink = pBilink->GetNext();
|
|
|
|
|
|
DPFX(DPFPREP, 5, "Removing UPnP device 0x%p cached mapping 0x%p.",
|
|
this, pCacheMap);
|
|
|
|
pCacheMap->m_blList.RemoveFromList();
|
|
delete pCacheMap;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteWaitingForContent"
|
|
inline void NoteWaitingForContent(const DWORD dwContentLength, const DWORD dwHTTPResponseCode)
|
|
{
|
|
DNASSERT(this->m_dwExpectedContentLength == 0);
|
|
this->m_dwExpectedContentLength = dwContentLength;
|
|
this->m_dwHTTPResponseCode = dwHTTPResponseCode;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::NoteNotWaitingForContent"
|
|
inline void NoteNotWaitingForContent(void)
|
|
{
|
|
DNASSERT(this->m_dwExpectedContentLength != 0);
|
|
this->m_dwExpectedContentLength = 0;
|
|
this->m_dwHTTPResponseCode = 0;
|
|
};
|
|
|
|
inline BOOL IsWaitingForContent(void) const { return ((this->m_dwExpectedContentLength != 0) ? TRUE : FALSE); };
|
|
inline DWORD GetExpectedContentSize(void) const { return this->m_dwExpectedContentLength; };
|
|
inline DWORD GetHTTPResponseCode(void) const { return this->m_dwHTTPResponseCode; };
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::StartWaitingForControlResponse"
|
|
inline void StartWaitingForControlResponse(CONTROLRESPONSETYPE ControlResponseType,
|
|
PUPNP_CONTROLRESPONSE_INFO pControlResponseInfo)
|
|
{
|
|
DNASSERT(ControlResponseType != CONTROLRESPONSETYPE_NONE);
|
|
|
|
DNASSERT(! (this->m_dwFlags & UPNPDEVICE_WAITINGFORCONTROLRESPONSE));
|
|
this->m_dwFlags |= UPNPDEVICE_WAITINGFORCONTROLRESPONSE;
|
|
|
|
this->m_ControlResponseType = ControlResponseType;
|
|
this->m_pControlResponseInfo = pControlResponseInfo;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CUPnPDevice::StopWaitingForControlResponse"
|
|
inline void StopWaitingForControlResponse(void)
|
|
{
|
|
this->m_dwFlags &= ~UPNPDEVICE_WAITINGFORCONTROLRESPONSE;
|
|
|
|
this->m_ControlResponseType = CONTROLRESPONSETYPE_NONE;
|
|
this->m_pControlResponseInfo = NULL;
|
|
};
|
|
|
|
inline BOOL IsWaitingForControlResponse(void) const { return ((this->m_dwFlags & UPNPDEVICE_WAITINGFORCONTROLRESPONSE) ? TRUE : FALSE); };
|
|
|
|
inline CONTROLRESPONSETYPE GetControlResponseType(void) const { return this->m_ControlResponseType; };
|
|
inline PUPNP_CONTROLRESPONSE_INFO GetControlResponseInfo(void) { return this->m_pControlResponseInfo; };
|
|
|
|
|
|
|
|
CBilink m_blList; // list of all the UPnP devices known
|
|
|
|
|
|
private:
|
|
BYTE m_Sig[4]; // debugging signature ('UPDV')
|
|
|
|
LONG m_lRefCount; // reference count for this object
|
|
DWORD m_dwFlags; // flags indicating current state of UPnP device
|
|
DWORD m_dwID; // unique identifier used to correlate crash registry entries with UPnP devices
|
|
CDevice * m_pOwningDevice; // pointer to owning device object
|
|
char * m_pszLocationURL; // control location URL string
|
|
SOCKADDR_IN m_saddrinHost; // UPnP device host address
|
|
SOCKADDR_IN m_saddrinControl; // UPnP device control address
|
|
char * m_pszUSN; // device's Unique Service Name
|
|
char * m_pszServiceControlURL; // URL used to control WANIPConnectionService
|
|
SOCKET m_sControl; // TCP socket with connection to the UPnP device
|
|
char * m_pcReceiveBuffer; // pointer to receive buffer
|
|
DWORD m_dwReceiveBufferSize; // size of receive buffer
|
|
char * m_pcReceiveBufferStart; // pointer to start of actual data in receive buffer (anything before this is just wasted space)
|
|
DWORD m_dwUsedReceiveBufferSize; // size of receive buffer actually filled with data (beginning at m_pcReceiveBufferStart)
|
|
DWORD m_dwRemainingReceiveBufferSize; // size of receive buffer that can hold more data (after m_pcReceiveBufferStart + m_dwUsedReceiveBufferSize)
|
|
DWORD m_dwExternalIPAddressV4; // IP v4 external IP address of this UPnP device
|
|
CBilink m_blCachedMaps; // list of cached mappings for query addresses performed on this UPnP device
|
|
|
|
DWORD m_dwExpectedContentLength; // expected size of message content, or 0 if no headers have been read
|
|
DWORD m_dwHTTPResponseCode; // HTTP response code previously parsed, if waiting for content
|
|
|
|
CONTROLRESPONSETYPE m_ControlResponseType; // type of response expected
|
|
PUPNP_CONTROLRESPONSE_INFO m_pControlResponseInfo; // place to store info from a received response
|
|
};
|
|
|