From: longinus Date: Thu, 10 Feb 2011 10:29:30 +0000 (+0000) Subject: fix memory leak, thanks to Valgrind X-Git-Url: http://git.osdn.net/view?p=rec10%2Frec10-git.git;a=commitdiff_plain;h=27219f6be039cc2fc5a4457495cca664ee7a417e fix memory leak, thanks to Valgrind git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/rec10@828 4e526526-5e11-4fc0-8910-f8fd03428081 --- diff --git a/b25-remote/BCasCard.cpp b/b25-remote/BCasCard.cpp index 7d8387f..893ea22 100755 --- a/b25-remote/BCasCard.cpp +++ b/b25-remote/BCasCard.cpp @@ -1,361 +1,364 @@ -// BcasCard.cpp: CBcasCard ƒNƒ‰ƒX‚̃Cƒ“ƒvƒŠƒƒ“ƒe[ƒVƒ‡ƒ“ -// -////////////////////////////////////////////////////////////////////// - -#include "W2L.h" -#include "BCasCard.h" - -#ifdef _DEBUG -#undef THIS_FILE -static char THIS_FILE[]=__FILE__; -#define new DEBUG_NEW -#endif - - -//#pragma comment(lib, "WinScard.lib") - - -using std::auto_ptr; - - -CBcasCard::CBcasCard() - : m_hBcasCard(NULL) - , m_bIsEstablish(false) - , m_dwLastError(BCEC_NOERROR) -{ - // “à•”ó‘ԏ‰Šú‰» - memset(&m_BcasCardInfo, 0, sizeof(m_BcasCardInfo)); - memset(&m_EcmStatus, 0, sizeof(m_EcmStatus)); - - // ƒŠƒ\[ƒXƒ}ƒl[ƒWƒƒƒRƒ“ƒeƒLƒXƒgŠm—§ - if(::SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &m_ScardContext) != SCARD_S_SUCCESS){ - m_dwLastError = BCEC_NOTESTABLISHED; - } - else{ - m_bIsEstablish = true; - - // ƒJ[ƒhƒŠ[ƒ_—ñ‹“ - EnumCardReader(); - } -} - -CBcasCard::~CBcasCard() -{ - CloseCard(); - - // ƒŠƒ\[ƒXƒ}ƒl[ƒWƒƒƒRƒ“ƒeƒLƒXƒg‚ÌŠJ•ú - if(m_bIsEstablish)::SCardReleaseContext(m_ScardContext); -} - -const DWORD CBcasCard::GetCardReaderNum(void) const -{ - // ƒJ[ƒhƒŠ[ƒ_[”‚ð•Ô‚· - return m_CardReaderArray.size(); -} - -LPCTSTR CBcasCard::GetCardReaderName(const DWORD dwIndex) const -{ - // ƒJ[ƒhƒŠ[ƒ_[–¼‚ð•Ô‚· - return (dwIndex < GetCardReaderNum())? m_CardReaderArray[dwIndex].c_str() : NULL; -} - -const bool CBcasCard::OpenCard(LPCTSTR lpszReader) -{ - // ƒŠƒ\[ƒXƒ}ƒl[ƒWƒƒƒRƒ“ƒeƒLƒXƒg‚ÌŠm—§ - if(!m_bIsEstablish){ - m_dwLastError = BCEC_NOTESTABLISHED; - return false; - } - - // ˆê’UƒNƒ[ƒY‚·‚é - CloseCard(); - - - if(lpszReader){ - // Žw’肳‚ꂽƒJ[ƒhƒŠ[ƒ_‚ɑ΂µ‚ăI[ƒvƒ“‚ðŽŽ‚Ý‚é - DWORD dwActiveProtocol = SCARD_PROTOCOL_UNDEFINED; - - if(::SCardConnect(m_ScardContext, lpszReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &m_hBcasCard, &dwActiveProtocol) != SCARD_S_SUCCESS){ - m_dwLastError = BCEC_CARDOPENERROR; - return false; - } - - if(dwActiveProtocol != SCARD_PROTOCOL_T1){ - CloseCard(); - m_dwLastError = BCEC_CARDOPENERROR; - return false; - } - } - else{ - // ‘S‚ẴJ[ƒhƒŠ[ƒ_‚ɑ΂µ‚ăI[ƒvƒ“‚ðŽŽ‚Ý‚é - DWORD dwIndex = 0UL; - - while(GetCardReaderName(dwIndex)){ - if(OpenCard(GetCardReaderName(dwIndex++)))return true; - } - - return false; - } - - // ƒJ[ƒh‰Šú‰» - if(!InitialSetting())return false; - - m_dwLastError = BCEC_NOERROR; - - return true; -} - -void CBcasCard::CloseCard(void) -{ - // ƒJ[ƒh‚ðƒNƒ[ƒY‚·‚é - if(m_hBcasCard){ - ::SCardDisconnect(m_hBcasCard, SCARD_LEAVE_CARD); - m_hBcasCard = NULL; - } -} - -const DWORD CBcasCard::GetLastError(void) const -{ - // ÅŒã‚É”­¶‚µ‚½ƒGƒ‰[‚ð•Ô‚· - return m_dwLastError; -} - -const bool CBcasCard::EnumCardReader(void) -{ - // ƒJ[ƒhƒŠ[ƒ_‚ð—ñ‹“‚·‚é - DWORD dwBuffSize = 0UL; - - switch(::SCardListReaders(m_ScardContext, NULL, NULL, &dwBuffSize)){ - case SCARD_E_NO_READERS_AVAILABLE : - // ƒJ[ƒhƒŠ[ƒ_‚ªŒ©‚‚©‚ç‚È‚¢ - m_dwLastError = BCEC_NOCARDREADERS; - return false; - - case SCARD_S_SUCCESS : - // ƒoƒbƒtƒ@ƒTƒCƒYŽæ“¾¬Œ÷ - break; - - default: - // ƒGƒ‰[ - m_dwLastError = BCEC_INTERNALERROR; - return false; - } - - // ƒoƒbƒtƒ@Šm•Û - auto_ptr szReaders(new TCHAR[dwBuffSize]); - - switch(::SCardListReaders(m_ScardContext, NULL, szReaders.get(), &dwBuffSize)){ - case SCARD_E_NO_READERS_AVAILABLE : - // ƒJ[ƒhƒŠ[ƒ_‚ªŒ©‚‚©‚ç‚È‚¢ - m_dwLastError = BCEC_NOCARDREADERS; - return false; - - case SCARD_S_SUCCESS : { - // ƒJ[ƒhƒŠ[ƒ_–¼•Û‘¶ - LPTSTR lpszCurReader = szReaders.get(); - m_CardReaderArray.clear(); - - while(*lpszCurReader){ - m_CardReaderArray.push_back(lpszCurReader); - lpszCurReader += m_CardReaderArray.back().length() + 1UL; - } - - break; - } - - default: - // ƒGƒ‰[ - m_dwLastError = BCEC_INTERNALERROR; - return false; - } - - m_dwLastError = BCEC_NOERROR; - - return true; -} - -const bool CBcasCard::TransmitCommand(const BYTE *pSendData, const DWORD dwSendSize, BYTE *pRecvData, const DWORD dwMaxRecv, DWORD *pdwRecvSize) -{ - DWORD dwRecvSize = dwMaxRecv; - - // ƒf[ƒ^‘—ŽóM - DWORD dwReturn = ::SCardTransmit(m_hBcasCard, SCARD_PCI_T1, pSendData, dwSendSize, NULL, pRecvData, &dwRecvSize); - - // ŽóMƒTƒCƒYŠi”[ - if(pdwRecvSize)*pdwRecvSize = dwRecvSize; - - return (dwReturn == SCARD_S_SUCCESS)? true : false; -} - -const bool CBcasCard::InitialSetting(void) -{ - static const BYTE InitSettingCmd[] = {0x90U, 0x30U, 0x00U, 0x00U, 0x00U}; - - // uInitial Setting Conditions Commandv‚ðˆ—‚·‚é - if(!m_hBcasCard){ - m_dwLastError = BCEC_CARDNOTOPEN; - return false; - } - - // ƒoƒbƒtƒ@€”õ - DWORD dwRecvSize = 0UL; - BYTE RecvData[1024]; - memset(RecvData, 0, sizeof(RecvData)); - - // ƒRƒ}ƒ“ƒh‘—M - if(!TransmitCommand(InitSettingCmd, sizeof(InitSettingCmd), RecvData, sizeof(RecvData), &dwRecvSize)){ - m_dwLastError = BCEC_TRANSMITERROR; - return false; - } - - if(dwRecvSize < 57UL){ - m_dwLastError = BCEC_TRANSMITERROR; - return false; - } - - // ƒŒƒXƒ|ƒ“ƒX‰ðÍ - memcpy(m_BcasCardInfo.BcasCardID, &RecvData[8], 6UL); // +8 Card ID - memcpy(m_BcasCardInfo.SystemKey, &RecvData[16], 32UL); // +16 Descrambling system key - memcpy(m_BcasCardInfo.InitialCbc, &RecvData[48], 8UL); // +48 Descrambler CBC initial value - - // ECMƒXƒe[ƒ^ƒX‰Šú‰» - memset(&m_EcmStatus, 0, sizeof(m_EcmStatus)); - - return true; -} - -const BYTE * CBcasCard::GetBcasCardID(void) -{ - // Card ID ‚ð•Ô‚· - if(!m_hBcasCard){ - m_dwLastError = BCEC_CARDNOTOPEN; - return NULL; - } - - m_dwLastError = BCEC_NOERROR; - - return m_BcasCardInfo.BcasCardID; -} - -const BYTE * CBcasCard::GetInitialCbc(void) -{ - // Descrambler CBC Initial Value ‚ð•Ô‚· - if(!m_hBcasCard){ - m_dwLastError = BCEC_CARDNOTOPEN; - return NULL; - } - - m_dwLastError = BCEC_NOERROR; - - return m_BcasCardInfo.InitialCbc; -} - -const BYTE * CBcasCard::GetSystemKey(void) -{ - // Descrambling System Key ‚ð•Ô‚· - if(!m_hBcasCard){ - m_dwLastError = BCEC_CARDNOTOPEN; - return NULL; - } - - m_dwLastError = BCEC_NOERROR; - - return m_BcasCardInfo.SystemKey; -} - -const BYTE * CBcasCard::GetKsFromEcm(const BYTE *pEcmData, const DWORD dwEcmSize) -{ - static const BYTE EcmReceiveCmd[] = {0x90U, 0x34U, 0x00U, 0x00U}; - - // uECM Receive Commandv‚ðˆ—‚·‚é - if(!m_hBcasCard){ - m_dwLastError = BCEC_CARDNOTOPEN; - return NULL; - } - - // ECMƒTƒCƒY‚ðƒ`ƒFƒbƒN - if(!pEcmData || (dwEcmSize < 30UL) || (dwEcmSize > 256UL)){ - m_dwLastError = BCEC_BADARGUMENT; - return NULL; - } - - // ƒLƒƒƒbƒVƒ…‚ðƒ`ƒFƒbƒN‚·‚é - if(!StoreEcmData(pEcmData, dwEcmSize)){ - // ECM‚ª“¯ˆê‚̏ꍇ‚̓LƒƒƒbƒVƒ…Ï‚ÝKs‚ð•Ô‚· - m_dwLastError = BCEC_NOERROR; - return m_EcmStatus.KsData; - } - - // ƒoƒbƒtƒ@€”õ - DWORD dwRecvSize = 0UL; - BYTE SendData[1024]; - BYTE RecvData[1024]; - memset(RecvData, 0, sizeof(RecvData)); - - // ƒRƒ}ƒ“ƒh\’z - memcpy(SendData, EcmReceiveCmd, sizeof(EcmReceiveCmd)); // CLA, INS, P1, P2 - SendData[sizeof(EcmReceiveCmd)] = (BYTE)dwEcmSize; // COMMAND DATA LENGTH - memcpy(&SendData[sizeof(EcmReceiveCmd) + 1], pEcmData, dwEcmSize); // ECM - SendData[sizeof(EcmReceiveCmd) + dwEcmSize + 1] = 0x00U; // RESPONSE DATA LENGTH - - // ƒRƒ}ƒ“ƒh‘—M - if(!TransmitCommand(SendData, sizeof(EcmReceiveCmd) + dwEcmSize + 2UL, RecvData, sizeof(RecvData), &dwRecvSize)){ - memset(&m_EcmStatus, 0, sizeof(m_EcmStatus)); - m_dwLastError = BCEC_TRANSMITERROR; - return NULL; - } - - // ƒTƒCƒYƒ`ƒFƒbƒN - if(dwRecvSize != 25UL){ - memset(&m_EcmStatus, 0, sizeof(m_EcmStatus)); - m_dwLastError = BCEC_TRANSMITERROR; - return NULL; - } - - // ƒŒƒXƒ|ƒ“ƒX‰ðÍ - memcpy(m_EcmStatus.KsData, &RecvData[6], sizeof(m_EcmStatus.KsData)); - - // ƒŠƒ^[ƒ“ƒR[ƒh‰ðÍ - switch(((WORD)RecvData[4] << 8) | (WORD)RecvData[5]){ - // Purchased: Viewing - case 0x0200U : // Payment-deferred PPV - case 0x0400U : // Prepaid PPV - case 0x0800U : // Tier - m_dwLastError = BCEC_NOERROR; - return m_EcmStatus.KsData; - - // ã‹LˆÈŠO(Ž‹’®•s‰Â) - default : - m_dwLastError = BCEC_ECMREFUSED; - return NULL; - } -} - -const bool CBcasCard::StoreEcmData(const BYTE *pEcmData, const DWORD dwEcmSize) -{ - bool bUpdate = false; - - // ECMƒf[ƒ^”äŠr - if(m_EcmStatus.dwLastEcmSize != dwEcmSize){ - // ƒTƒCƒY‚ª•Ï‰»‚µ‚½ - bUpdate = true; - } - else{ - // ƒTƒCƒY‚ª“¯‚¶ê‡‚̓f[ƒ^‚ðƒ`ƒFƒbƒN‚·‚é - for(DWORD dwPos = 0UL ; dwPos < dwEcmSize ; dwPos++){ - if(pEcmData[dwPos] != m_EcmStatus.LastEcmData[dwPos]){ - // ƒf[ƒ^‚ª•sˆê’v - bUpdate = true; - break; - } - } - } - - // ECMƒf[ƒ^‚ð•Û‘¶‚·‚é - if(bUpdate){ - m_EcmStatus.dwLastEcmSize = dwEcmSize; - memcpy(m_EcmStatus.LastEcmData, pEcmData, dwEcmSize); - } - - return bUpdate; -} +// BcasCard.cpp: CBcasCard クラスのインプリメンテーション +// +////////////////////////////////////////////////////////////////////// + +#include "W2L.h" +#include "BCasCard.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#define new DEBUG_NEW +#endif + + +//#pragma comment(lib, "WinScard.lib") + + +using std::auto_ptr; + + +CBcasCard::CBcasCard() + : m_hBcasCard(NULL) + , m_bIsEstablish(false) + , m_dwLastError(BCEC_NOERROR) +{ + // 内部状態初期化 + memset(&m_BcasCardInfo, 0, sizeof(m_BcasCardInfo)); + memset(&m_EcmStatus, 0, sizeof(m_EcmStatus)); + + // リソースマネージャコンテキスト確立 + if(::SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &m_ScardContext) != SCARD_S_SUCCESS){ + m_dwLastError = BCEC_NOTESTABLISHED; + } + else{ + m_bIsEstablish = true; + + // カードリーダ列挙 + EnumCardReader(); + } +} + +CBcasCard::~CBcasCard() +{ + CloseCard(); + + // リソースマネージャコンテキストの開放 + if(m_bIsEstablish)::SCardReleaseContext(m_ScardContext); +} + +const DWORD CBcasCard::GetCardReaderNum(void) const +{ + // カードリーダー数を返す + return m_CardReaderArray.size(); +} + +LPCTSTR CBcasCard::GetCardReaderName(const DWORD dwIndex) const +{ + // カードリーダー名を返す + return (dwIndex < GetCardReaderNum())? m_CardReaderArray[dwIndex].c_str() : NULL; +} + +const bool CBcasCard::OpenCard(LPCTSTR lpszReader) +{ + // リソースマネージャコンテキストの確立 + if(!m_bIsEstablish){ + m_dwLastError = BCEC_NOTESTABLISHED; + return false; + } + + // 一旦クローズする + CloseCard(); + + + if(lpszReader){ + // 指定されたカードリーダに対してオープンを試みる + DWORD dwActiveProtocol = SCARD_PROTOCOL_UNDEFINED; + + if(::SCardConnect(m_ScardContext, lpszReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &m_hBcasCard, &dwActiveProtocol) != SCARD_S_SUCCESS){ + m_dwLastError = BCEC_CARDOPENERROR; + return false; + } + + if(dwActiveProtocol != SCARD_PROTOCOL_T1){ + CloseCard(); + m_dwLastError = BCEC_CARDOPENERROR; + return false; + } + } + else{ + // 全てのカードリーダに対してオープンを試みる + DWORD dwIndex = 0UL; + + while(GetCardReaderName(dwIndex)){ + if(OpenCard(GetCardReaderName(dwIndex++)))return true; + } + + return false; + } + + // カード初期化 + if(!InitialSetting())return false; + + m_dwLastError = BCEC_NOERROR; + + return true; +} + +void CBcasCard::CloseCard(void) +{ + // カードをクローズする + if(m_hBcasCard){ + ::SCardDisconnect(m_hBcasCard, SCARD_LEAVE_CARD); + m_hBcasCard = NULL; + } +} + +const DWORD CBcasCard::GetLastError(void) const +{ + // 最後に発生したエラーを返す + return m_dwLastError; +} + +const bool CBcasCard::EnumCardReader(void) +{ + // カードリーダを列挙する + DWORD dwBuffSize = 0UL; + + switch(::SCardListReaders(m_ScardContext, NULL, NULL, &dwBuffSize)){ + case SCARD_E_NO_READERS_AVAILABLE : + // カードリーダが見つからない + m_dwLastError = BCEC_NOCARDREADERS; + return false; + + case SCARD_S_SUCCESS : + // バッファサイズ取得成功 + break; + + default: + // エラー + m_dwLastError = BCEC_INTERNALERROR; + return false; + } + + // バッファ確保 + // auto_ptr cannot be used for array + // auto_ptr szReaders(new TCHAR[dwBuffSize]); + std::string szReaders; + szReaders.resize(dwBuffSize); + + switch(::SCardListReaders(m_ScardContext, NULL, (char*)szReaders.data(), &dwBuffSize)){ + case SCARD_E_NO_READERS_AVAILABLE : + // カードリーダが見つからない + m_dwLastError = BCEC_NOCARDREADERS; + return false; + + case SCARD_S_SUCCESS : { + // カードリーダ名保存 + LPCTSTR lpszCurReader = szReaders.data(); + m_CardReaderArray.clear(); + + while(*lpszCurReader){ + m_CardReaderArray.push_back(lpszCurReader); + lpszCurReader += m_CardReaderArray.back().length() + 1UL; + } + + break; + } + + default: + // エラー + m_dwLastError = BCEC_INTERNALERROR; + return false; + } + + m_dwLastError = BCEC_NOERROR; + + return true; +} + +const bool CBcasCard::TransmitCommand(const BYTE *pSendData, const DWORD dwSendSize, BYTE *pRecvData, const DWORD dwMaxRecv, DWORD *pdwRecvSize) +{ + DWORD dwRecvSize = dwMaxRecv; + + // データ送受信 + DWORD dwReturn = ::SCardTransmit(m_hBcasCard, SCARD_PCI_T1, pSendData, dwSendSize, NULL, pRecvData, &dwRecvSize); + + // 受信サイズ格納 + if(pdwRecvSize)*pdwRecvSize = dwRecvSize; + + return (dwReturn == SCARD_S_SUCCESS)? true : false; +} + +const bool CBcasCard::InitialSetting(void) +{ + static const BYTE InitSettingCmd[] = {0x90U, 0x30U, 0x00U, 0x00U, 0x00U}; + + // 「Initial Setting Conditions Command」を処理する + if(!m_hBcasCard){ + m_dwLastError = BCEC_CARDNOTOPEN; + return false; + } + + // バッファ準備 + DWORD dwRecvSize = 0UL; + BYTE RecvData[1024]; + memset(RecvData, 0, sizeof(RecvData)); + + // コマンド送信 + if(!TransmitCommand(InitSettingCmd, sizeof(InitSettingCmd), RecvData, sizeof(RecvData), &dwRecvSize)){ + m_dwLastError = BCEC_TRANSMITERROR; + return false; + } + + if(dwRecvSize < 57UL){ + m_dwLastError = BCEC_TRANSMITERROR; + return false; + } + + // レスポンス解析 + memcpy(m_BcasCardInfo.BcasCardID, &RecvData[8], 6UL); // +8 Card ID + memcpy(m_BcasCardInfo.SystemKey, &RecvData[16], 32UL); // +16 Descrambling system key + memcpy(m_BcasCardInfo.InitialCbc, &RecvData[48], 8UL); // +48 Descrambler CBC initial value + + // ECMステータス初期化 + memset(&m_EcmStatus, 0, sizeof(m_EcmStatus)); + + return true; +} + +const BYTE * CBcasCard::GetBcasCardID(void) +{ + // Card ID を返す + if(!m_hBcasCard){ + m_dwLastError = BCEC_CARDNOTOPEN; + return NULL; + } + + m_dwLastError = BCEC_NOERROR; + + return m_BcasCardInfo.BcasCardID; +} + +const BYTE * CBcasCard::GetInitialCbc(void) +{ + // Descrambler CBC Initial Value を返す + if(!m_hBcasCard){ + m_dwLastError = BCEC_CARDNOTOPEN; + return NULL; + } + + m_dwLastError = BCEC_NOERROR; + + return m_BcasCardInfo.InitialCbc; +} + +const BYTE * CBcasCard::GetSystemKey(void) +{ + // Descrambling System Key を返す + if(!m_hBcasCard){ + m_dwLastError = BCEC_CARDNOTOPEN; + return NULL; + } + + m_dwLastError = BCEC_NOERROR; + + return m_BcasCardInfo.SystemKey; +} + +const BYTE * CBcasCard::GetKsFromEcm(const BYTE *pEcmData, const DWORD dwEcmSize) +{ + static const BYTE EcmReceiveCmd[] = {0x90U, 0x34U, 0x00U, 0x00U}; + + // 「ECM Receive Command」を処理する + if(!m_hBcasCard){ + m_dwLastError = BCEC_CARDNOTOPEN; + return NULL; + } + + // ECMサイズをチェック + if(!pEcmData || (dwEcmSize < 30UL) || (dwEcmSize > 256UL)){ + m_dwLastError = BCEC_BADARGUMENT; + return NULL; + } + + // キャッシュをチェックする + if(!StoreEcmData(pEcmData, dwEcmSize)){ + // ECMが同一の場合はキャッシュ済みKsを返す + m_dwLastError = BCEC_NOERROR; + return m_EcmStatus.KsData; + } + + // バッファ準備 + DWORD dwRecvSize = 0UL; + BYTE SendData[1024]; + BYTE RecvData[1024]; + memset(RecvData, 0, sizeof(RecvData)); + + // コマンド構築 + memcpy(SendData, EcmReceiveCmd, sizeof(EcmReceiveCmd)); // CLA, INS, P1, P2 + SendData[sizeof(EcmReceiveCmd)] = (BYTE)dwEcmSize; // COMMAND DATA LENGTH + memcpy(&SendData[sizeof(EcmReceiveCmd) + 1], pEcmData, dwEcmSize); // ECM + SendData[sizeof(EcmReceiveCmd) + dwEcmSize + 1] = 0x00U; // RESPONSE DATA LENGTH + + // コマンド送信 + if(!TransmitCommand(SendData, sizeof(EcmReceiveCmd) + dwEcmSize + 2UL, RecvData, sizeof(RecvData), &dwRecvSize)){ + memset(&m_EcmStatus, 0, sizeof(m_EcmStatus)); + m_dwLastError = BCEC_TRANSMITERROR; + return NULL; + } + + // サイズチェック + if(dwRecvSize != 25UL){ + memset(&m_EcmStatus, 0, sizeof(m_EcmStatus)); + m_dwLastError = BCEC_TRANSMITERROR; + return NULL; + } + + // レスポンス解析 + memcpy(m_EcmStatus.KsData, &RecvData[6], sizeof(m_EcmStatus.KsData)); + + // リターンコード解析 + switch(((WORD)RecvData[4] << 8) | (WORD)RecvData[5]){ + // Purchased: Viewing + case 0x0200U : // Payment-deferred PPV + case 0x0400U : // Prepaid PPV + case 0x0800U : // Tier + m_dwLastError = BCEC_NOERROR; + return m_EcmStatus.KsData; + + // 上記以外(視聴不可) + default : + m_dwLastError = BCEC_ECMREFUSED; + return NULL; + } +} + +const bool CBcasCard::StoreEcmData(const BYTE *pEcmData, const DWORD dwEcmSize) +{ + bool bUpdate = false; + + // ECMデータ比較 + if(m_EcmStatus.dwLastEcmSize != dwEcmSize){ + // サイズが変化した + bUpdate = true; + } + else{ + // サイズが同じ場合はデータをチェックする + for(DWORD dwPos = 0UL ; dwPos < dwEcmSize ; dwPos++){ + if(pEcmData[dwPos] != m_EcmStatus.LastEcmData[dwPos]){ + // データが不一致 + bUpdate = true; + break; + } + } + } + + // ECMデータを保存する + if(bUpdate){ + m_EcmStatus.dwLastEcmSize = dwEcmSize; + memcpy(m_EcmStatus.LastEcmData, pEcmData, dwEcmSize); + } + + return bUpdate; +} diff --git a/b25-remote/BCasCard.h b/b25-remote/BCasCard.h index e793203..c3cebb6 100755 --- a/b25-remote/BCasCard.h +++ b/b25-remote/BCasCard.h @@ -1,85 +1,85 @@ -// BcasCard.h: CBcasCard ƒNƒ‰ƒX‚̃Cƒ“ƒ^[ƒtƒFƒCƒX -// -////////////////////////////////////////////////////////////////////// - -#pragma once - - -#include -#include -#include -#include - - -using std::vector; -using std::wstring; -using std::string; - - -// ƒGƒ‰[ƒR[ƒh -#define BCEC_NOERROR 0x00000000UL // ƒGƒ‰[‚È‚µ -#define BCEC_INTERNALERROR 0x00000001UL // “à•”ƒGƒ‰[ -#define BCEC_NOTESTABLISHED 0x00000002UL // ƒRƒ“ƒeƒLƒXƒgŠm—§Ž¸”s -#define BCEC_NOCARDREADERS 0x00000003UL // ƒJ[ƒhƒŠ[ƒ_‚ª‚È‚¢ -#define BCEC_ALREADYOPEN 0x00000004UL // Šù‚ɃI[ƒvƒ“Ï‚Ý -#define BCEC_CARDOPENERROR 0x00000005UL // ƒJ[ƒhƒI[ƒvƒ“Ž¸”s -#define BCEC_CARDNOTOPEN 0x00000006UL // ƒJ[ƒh–¢ƒI[ƒvƒ“ -#define BCEC_TRANSMITERROR 0x00000007UL // ’ʐMƒGƒ‰[ -#define BCEC_BADARGUMENT 0x00000008UL // ˆø”‚ª•s³ -#define BCEC_ECMREFUSED 0x00000009UL // ECMŽó•t‹‘”Û - - -class CBcasCard -{ -public: - CBcasCard(); - ~CBcasCard(); - - const DWORD GetCardReaderNum(void) const; - LPCTSTR GetCardReaderName(const DWORD dwIndex = 0UL) const; - - const bool OpenCard(LPCTSTR lpszReader = NULL); - void CloseCard(void); - - const BYTE * GetBcasCardID(void); - const BYTE * GetInitialCbc(void); - const BYTE * GetSystemKey(void); - const BYTE * GetKsFromEcm(const BYTE *pEcmData, const DWORD dwEcmSize); - - const DWORD GetLastError(void) const; - -protected: - const bool EnumCardReader(void); - const bool TransmitCommand(const BYTE *pSendData, const DWORD dwSendSize, BYTE *pRecvData, const DWORD dwMaxRecv, DWORD *pdwRecvSize = NULL); - const bool InitialSetting(void); - - SCARDCONTEXT m_ScardContext; - SCARDHANDLE m_hBcasCard; - - bool m_bIsEstablish; - -#ifdef _UNICODE - vector m_CardReaderArray; -#else - vector m_CardReaderArray; -#endif - - struct TAG_BCASCARDINFO - { - BYTE BcasCardID[6]; // Card ID - BYTE SystemKey[32]; // Descrambling system key - BYTE InitialCbc[8]; // Descrambler CBC initial value - } m_BcasCardInfo; - - struct TAG_ECMSTATUS - { - DWORD dwLastEcmSize; // ÅŒã‚É–â‚¢‡‚킹‚Ì‚ ‚Á‚½ECMƒTƒCƒY - BYTE LastEcmData[256]; // ÅŒã‚É–â‚¢‡‚킹‚Ì‚ ‚Á‚½ECMƒf[ƒ^ - BYTE KsData[16]; // Ks Odd + Even - } m_EcmStatus; - - DWORD m_dwLastError; - -private: - const bool StoreEcmData(const BYTE *pEcmData, const DWORD dwEcmSize); -}; +// BcasCard.h: CBcasCard クラスのインターフェイス +// +////////////////////////////////////////////////////////////////////// + +#pragma once + + +#include +#include +#include +#include + + +using std::vector; +using std::wstring; +using std::string; + + +// エラーコード +#define BCEC_NOERROR 0x00000000UL // エラーなし +#define BCEC_INTERNALERROR 0x00000001UL // 内部エラー +#define BCEC_NOTESTABLISHED 0x00000002UL // コンテキスト確立失敗 +#define BCEC_NOCARDREADERS 0x00000003UL // カードリーダがない +#define BCEC_ALREADYOPEN 0x00000004UL // 既にオープン済み +#define BCEC_CARDOPENERROR 0x00000005UL // カードオープン失敗 +#define BCEC_CARDNOTOPEN 0x00000006UL // カード未オープン +#define BCEC_TRANSMITERROR 0x00000007UL // 通信エラー +#define BCEC_BADARGUMENT 0x00000008UL // 引数が不正 +#define BCEC_ECMREFUSED 0x00000009UL // ECM受付拒否 + + +class CBcasCard +{ +public: + CBcasCard(); + ~CBcasCard(); + + const DWORD GetCardReaderNum(void) const; + LPCTSTR GetCardReaderName(const DWORD dwIndex = 0UL) const; + + const bool OpenCard(LPCTSTR lpszReader = NULL); + void CloseCard(void); + + const BYTE * GetBcasCardID(void); + const BYTE * GetInitialCbc(void); + const BYTE * GetSystemKey(void); + const BYTE * GetKsFromEcm(const BYTE *pEcmData, const DWORD dwEcmSize); + + const DWORD GetLastError(void) const; + +protected: + const bool EnumCardReader(void); + const bool TransmitCommand(const BYTE *pSendData, const DWORD dwSendSize, BYTE *pRecvData, const DWORD dwMaxRecv, DWORD *pdwRecvSize = NULL); + const bool InitialSetting(void); + + SCARDCONTEXT m_ScardContext; + SCARDHANDLE m_hBcasCard; + + bool m_bIsEstablish; + +#ifdef _UNICODE + vector m_CardReaderArray; +#else + vector m_CardReaderArray; +#endif + + struct TAG_BCASCARDINFO + { + BYTE BcasCardID[6]; // Card ID + BYTE SystemKey[32]; // Descrambling system key + BYTE InitialCbc[8]; // Descrambler CBC initial value + } m_BcasCardInfo; + + struct TAG_ECMSTATUS + { + DWORD dwLastEcmSize; // 最後に問い合わせのあったECMサイズ + BYTE LastEcmData[256]; // 最後に問い合わせのあったECMデータ + BYTE KsData[16]; // Ks Odd + Even + } m_EcmStatus; + + DWORD m_dwLastError; + +private: + const bool StoreEcmData(const BYTE *pEcmData, const DWORD dwEcmSize); +}; diff --git a/b25-remote/CasClient.cpp b/b25-remote/CasClient.cpp index 4b6c6fb..74fbb17 100755 --- a/b25-remote/CasClient.cpp +++ b/b25-remote/CasClient.cpp @@ -1,97 +1,98 @@ -// CasClient.cpp: CCasClient ƒNƒ‰ƒX‚̃Cƒ“ƒvƒŠƒƒ“ƒe[ƒVƒ‡ƒ“ -// -////////////////////////////////////////////////////////////////////// - -#include -#include "W2L.h" +// CasClient.cpp: CCasClient クラスのインプリメンテーション +// +////////////////////////////////////////////////////////////////////// + +#include +#include "W2L.h" #include "CasClient.h" - - -#define TCP_TIMEOUT 1000UL // 1•b - - -CCasClient::CCasClient(ICasClientHandler *pEventHandler, CSmartSock *pSocket) - : CBcasCard() - , m_pSocket(pSocket) - , m_pEventHandler(pEventHandler) - , m_hClientThread(NULL) -{ - // ƒNƒ‰ƒCƒAƒ“ƒgƒXƒŒƒbƒh‹N“® - pthread_create(&m_hClientThread, NULL, CCasClient::ClientThreadRaw, (LPVOID)this); - if(!m_hClientThread){ + + +#define TCP_TIMEOUT 1000UL // 1秒 + + +CCasClient::CCasClient(ICasClientHandler *pEventHandler, CSmartSock *pSocket) + : CBcasCard() + , m_pSocket(pSocket) + , m_pEventHandler(pEventHandler) + , m_hClientThread(NULL) +{ + // クライアントスレッド起動 + pthread_create(&m_hClientThread, NULL, CCasClient::ClientThreadRaw, (LPVOID)this); + if(!m_hClientThread){ printf("ClientThread failed\n"); - delete this; - } + delete this; + } + pthread_detach(m_hClientThread); printf("ClientThread started\n"); -} - -CCasClient::~CCasClient(void) -{ - delete m_pSocket; - if (m_hClientThread) pthread_join(m_hClientThread, NULL); -} - -void CCasClient::CloseClient(void) -{ - // ƒNƒ‰ƒCƒAƒ“ƒg‚ðØ’f‚·‚é - m_pSocket->Close(); -} - -void CCasClient::ClientThread(void) -{ - // ƒJ[ƒhƒŠ[ƒ_‚ðŠJ‚­ - if(!OpenCard())return; - - // ŽóMƒoƒbƒtƒ@ - BYTE byDataLen; - BYTE RecvBuf[256]; - DWORD dwRecvSize; - - // ƒƒbƒZ[ƒWŽóMƒ‹[ƒv - while(1){ - // ƒwƒbƒ_‚ðŽóM - if(!m_pSocket->Recv(&byDataLen, 1UL, TCP_TIMEOUT)){ - if(m_pSocket->GetLastError() == CSmartSock::EC_TIMEOUT)continue; - else break; +} + +CCasClient::~CCasClient(void) +{ + delete m_pSocket; + if (m_hClientThread) pthread_join(m_hClientThread, NULL); +} + +void CCasClient::CloseClient(void) +{ + // クライアントを切断する + m_pSocket->Close(); +} + +void CCasClient::ClientThread(void) +{ + // カードリーダを開く + if(!OpenCard())return; + + // 受信バッファ + BYTE byDataLen; + BYTE RecvBuf[256]; + DWORD dwRecvSize; + + // メッセージ受信ループ + while(1){ + // ヘッダを受信 + if(!m_pSocket->Recv(&byDataLen, 1UL, TCP_TIMEOUT)){ + if(m_pSocket->GetLastError() == CSmartSock::EC_TIMEOUT)continue; + else break; } - - // ƒf[ƒ^‚ðŽóM + + // データを受信 if(!m_pSocket->Recv(RecvBuf, byDataLen, TCP_TIMEOUT))break; - - // ƒJ[ƒh‘—ŽóM + + // カード送受信 if(!TransmitCommand(RecvBuf, byDataLen, &RecvBuf[1], sizeof(RecvBuf) - 1UL, &dwRecvSize))dwRecvSize = 0UL; - - // ƒf[ƒ^‚𑗐M - RecvBuf[0] = (BYTE)dwRecvSize; + + // データを送信 + RecvBuf[0] = (BYTE)dwRecvSize; if(!m_pSocket->Send(RecvBuf, dwRecvSize + 1UL, TCP_TIMEOUT))break; - } - + } + printf("ClientThread exited\n"); - // ƒJ[ƒhƒŠ[ƒ_‚ð•Â‚¶‚é - CloseCard(); -} - -void* CCasClient::ClientThreadRaw(LPVOID pParam) -{ - // ƒNƒ‰ƒCƒAƒ“ƒgƒXƒŒƒbƒh - CCasClient *pThis = static_cast(pParam); - - // Ú‘±ƒCƒxƒ“ƒg’Ê’m + // カードリーダを閉じる + CloseCard(); +} + +void* CCasClient::ClientThreadRaw(LPVOID pParam) +{ + // クライアントスレッド + CCasClient *pThis = static_cast(pParam); + + // 接続イベント通知 pThis->SendEvent(EID_CONNECTED); - - // ƒƒ“ƒoŠÖ”‚ɃŠƒ_ƒCƒŒƒNƒg‚·‚é + + // メンバ関数にリダイレクトする pThis->ClientThread(); - - // Ø’fƒCƒxƒ“ƒg’Ê’m + + // 切断イベント通知 pThis->SendEvent(EID_DISCONNECTED); - + delete pThis; - - return 0UL; -} - -void CCasClient::SendEvent(const DWORD dwEventID, PVOID pParam) -{ - // ƒnƒ“ƒhƒ‰‚ɃCƒxƒ“ƒg‚ð’Ê’m‚·‚é - if(m_pEventHandler)m_pEventHandler->OnCasClientEvent(this, dwEventID, pParam); -} + + return 0UL; +} + +void CCasClient::SendEvent(const DWORD dwEventID, PVOID pParam) +{ + // ハンドラにイベントを通知する + if(m_pEventHandler)m_pEventHandler->OnCasClientEvent(this, dwEventID, pParam); +} diff --git a/b25-remote/CasClient.h b/b25-remote/CasClient.h index ecd1c56..c17f47a 100755 --- a/b25-remote/CasClient.h +++ b/b25-remote/CasClient.h @@ -1,41 +1,41 @@ -// CasClient.h: CCasClient ƒNƒ‰ƒX‚̃Cƒ“ƒ^[ƒtƒFƒCƒX -// -////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "W2L.h" -#include "BCasCard.h" -#include "SmartSock.h" - - -class CCasClient : private CBcasCard -{ -public: - class ICasClientHandler - { - public: - virtual void OnCasClientEvent(CCasClient *pClient, const DWORD dwEventID, PVOID pParam) = 0; - }; - - enum - { - EID_CONNECTED, // ƒNƒ‰ƒCƒAƒ“ƒgÚ‘± - EID_DISCONNECTED // ƒNƒ‰ƒCƒAƒ“ƒgØ’f - }; - - CCasClient(ICasClientHandler *pEventHandler, CSmartSock *pSocket); - ~CCasClient(void); - - void CloseClient(void); - -protected: - void ClientThread(void); - static void* ClientThreadRaw(LPVOID pParam); - - void SendEvent(const DWORD dwEventID, PVOID pParam = NULL); - - CSmartSock *m_pSocket; - ICasClientHandler *m_pEventHandler; - pthread_t m_hClientThread; -}; +// CasClient.h: CCasClient クラスのインターフェイス +// +////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "W2L.h" +#include "BCasCard.h" +#include "SmartSock.h" + + +class CCasClient : private CBcasCard +{ +public: + class ICasClientHandler + { + public: + virtual void OnCasClientEvent(CCasClient *pClient, const DWORD dwEventID, PVOID pParam) = 0; + }; + + enum + { + EID_CONNECTED, // クライアント接続 + EID_DISCONNECTED // クライアント切断 + }; + + CCasClient(ICasClientHandler *pEventHandler, CSmartSock *pSocket); + ~CCasClient(void); + + void CloseClient(void); + +protected: + void ClientThread(void); + static void* ClientThreadRaw(LPVOID pParam); + + void SendEvent(const DWORD dwEventID, PVOID pParam = NULL); + + CSmartSock *m_pSocket; + ICasClientHandler *m_pEventHandler; + pthread_t m_hClientThread; +}; diff --git a/b25-remote/CasProxy.cpp b/b25-remote/CasProxy.cpp index dbf0330..85bf499 100755 --- a/b25-remote/CasProxy.cpp +++ b/b25-remote/CasProxy.cpp @@ -1,38 +1,38 @@ -// CasProxy.cpp: CCasProxy ƒNƒ‰ƒX‚̃Cƒ“ƒvƒŠƒƒ“ƒe[ƒVƒ‡ƒ“ -// -////////////////////////////////////////////////////////////////////// - - -#include "CasProxy.h" -#include - -#define TCP_TIMEOUT 1000UL // 1•b - - -DWORD CCasProxy::dwErrorDelayTime = 0UL; - - -CCasProxy::CCasProxy(void) -{ - -} - -CCasProxy::~CCasProxy(void) -{ - // ƒT[ƒo‚©‚çØ’f - m_Socket.Close(); -} - -const BOOL CCasProxy::Connect(void) -{ +// CasProxy.cpp: CCasProxy クラスのインプリメンテーション +// +////////////////////////////////////////////////////////////////////// + + +#include "CasProxy.h" +#include + +#define TCP_TIMEOUT 1000UL // 1秒 + + +DWORD CCasProxy::dwErrorDelayTime = 0UL; + + +CCasProxy::CCasProxy(void) +{ + +} + +CCasProxy::~CCasProxy(void) +{ + // サーバから切断 + m_Socket.Close(); +} + +const BOOL CCasProxy::Connect(void) +{ /* - // ƒGƒ‰[”­¶Žž‚̃K[ƒhƒCƒ“ƒ^[ƒoƒ‹ - if(dwErrorDelayTime){ - if((::GetTickCount() - dwErrorDelayTime) < TCP_TIMEOUT)return FALSE; - else dwErrorDelayTime = 0UL; - } -*/ - // ƒT[ƒo‚ɐڑ± + // エラー発生時のガードインターバル + if(dwErrorDelayTime){ + if((::GetTickCount() - dwErrorDelayTime) < TCP_TIMEOUT)return FALSE; + else dwErrorDelayTime = 0UL; + } +*/ + // サーバに接続 char* env = getenv("B25_SERVER_IP"); LPCTSTR lpszHost; WORD wPort; @@ -50,38 +50,38 @@ const BOOL CCasProxy::Connect(void) wPort = 6900; } - if(m_Socket.Connect(lpszHost, wPort, TCP_TIMEOUT)){ - return TRUE; - } + if(m_Socket.Connect(lpszHost, wPort, TCP_TIMEOUT)){ + return TRUE; + } else{ - //dwErrorDelayTime = ::GetTickCount(); - return FALSE; - } -} - -const DWORD CCasProxy::TransmitCommand(const BYTE *pSendData, const DWORD dwSendSize, BYTE *pRecvData) -{ - // ‘—Mƒf[ƒ^€”õ - BYTE SendBuf[256]; - SendBuf[0] = (BYTE)dwSendSize; - memcpy(&SendBuf[1], pSendData, dwSendSize); - - try{ - // ƒŠƒNƒGƒXƒg‘—M - if(!m_Socket.Send(SendBuf, dwSendSize + 1UL, TCP_TIMEOUT))throw (const DWORD)__LINE__; - - // ƒŒƒXƒ|ƒ“ƒXƒwƒbƒ_ŽóM - if(!m_Socket.Recv(SendBuf, 1UL, TCP_TIMEOUT))throw (const DWORD)__LINE__; - - // ƒŒƒXƒ|ƒ“ƒXƒf[ƒ^ŽóM - if(!m_Socket.Recv(pRecvData, SendBuf[0], TCP_TIMEOUT))throw (const DWORD)__LINE__; - } - catch(const DWORD dwLine){ - // ’ʐMƒGƒ‰[”­¶ - m_Socket.Close(); - return 0UL; - } - - return SendBuf[0]; + //dwErrorDelayTime = ::GetTickCount(); + return FALSE; + } +} + +const DWORD CCasProxy::TransmitCommand(const BYTE *pSendData, const DWORD dwSendSize, BYTE *pRecvData) +{ + // 送信データ準備 + BYTE SendBuf[256]; + SendBuf[0] = (BYTE)dwSendSize; + memcpy(&SendBuf[1], pSendData, dwSendSize); + + try{ + // リクエスト送信 + if(!m_Socket.Send(SendBuf, dwSendSize + 1UL, TCP_TIMEOUT))throw (const DWORD)__LINE__; + + // レスポンスヘッダ受信 + if(!m_Socket.Recv(SendBuf, 1UL, TCP_TIMEOUT))throw (const DWORD)__LINE__; + + // レスポンスデータ受信 + if(!m_Socket.Recv(pRecvData, SendBuf[0], TCP_TIMEOUT))throw (const DWORD)__LINE__; + } + catch(const DWORD dwLine){ + // 通信エラー発生 + m_Socket.Close(); + return 0UL; + } + + return SendBuf[0]; } diff --git a/b25-remote/CasProxy.h b/b25-remote/CasProxy.h index 2b0d6e4..15f9f8b 100755 --- a/b25-remote/CasProxy.h +++ b/b25-remote/CasProxy.h @@ -1,36 +1,36 @@ -// CasProxy.h: CCasProxy ƒNƒ‰ƒX‚̃Cƒ“ƒ^[ƒtƒFƒCƒX -// -////////////////////////////////////////////////////////////////////// - - -#pragma once - - -#include "SmartSock.h" -#include - -class CCasProxy -{ -public: - enum - { - CPEI_ENTERPROCESS, // ƒvƒƒZƒXŠJŽn’Ê’m - CPEI_EXITPROCESS, // ƒvƒƒZƒXI—¹’Ê’m - CPEI_GETSERVERIP, // ƒT[ƒoIPŽæ“¾ - CPEI_GETSERVERPORT, // ƒT[ƒoƒ|[ƒgŽæ“¾ - CPEI_CONNECTSUCCESS, // Ú‘±Š®—¹ - CPEI_CONNECTFAILED, // Ú‘±Ž¸”s - CPEI_DISCONNECTED // Ú‘±Ø’f - }; - - CCasProxy(void); - ~CCasProxy(void); - - const BOOL Connect(void); - const DWORD TransmitCommand(const BYTE *pSendData, const DWORD dwSendSize, BYTE *pRecvData); - -protected: - CSmartSock m_Socket; - - static DWORD dwErrorDelayTime; -}; +// CasProxy.h: CCasProxy クラスのインターフェイス +// +////////////////////////////////////////////////////////////////////// + + +#pragma once + + +#include "SmartSock.h" +#include + +class CCasProxy +{ +public: + enum + { + CPEI_ENTERPROCESS, // プロセス開始通知 + CPEI_EXITPROCESS, // プロセス終了通知 + CPEI_GETSERVERIP, // サーバIP取得 + CPEI_GETSERVERPORT, // サーバポート取得 + CPEI_CONNECTSUCCESS, // 接続完了 + CPEI_CONNECTFAILED, // 接続失敗 + CPEI_DISCONNECTED // 接続切断 + }; + + CCasProxy(void); + ~CCasProxy(void); + + const BOOL Connect(void); + const DWORD TransmitCommand(const BYTE *pSendData, const DWORD dwSendSize, BYTE *pRecvData); + +protected: + CSmartSock m_Socket; + + static DWORD dwErrorDelayTime; +}; diff --git a/b25-remote/CasServer.cpp b/b25-remote/CasServer.cpp index 4c733b8..4ae1883 100755 --- a/b25-remote/CasServer.cpp +++ b/b25-remote/CasServer.cpp @@ -1,110 +1,110 @@ -// CasServer.cpp: CCasServer ƒNƒ‰ƒX‚̃Cƒ“ƒvƒŠƒƒ“ƒe[ƒVƒ‡ƒ“ -// -////////////////////////////////////////////////////////////////////// - - -#include "CasServer.h" -#include "BCasCard.h" - +// CasServer.cpp: CCasServer クラスのインプリメンテーション +// +////////////////////////////////////////////////////////////////////// + + +#include "CasServer.h" +#include "BCasCard.h" + #define FALSE 0 -#define TRUE 1 - -CCasServer::CCasServer(ICasServerHandler *pEventHandler) - : m_pEventHandler(pEventHandler) - , m_hServerThread(NULL) -{ - -} - -CCasServer::~CCasServer(void) -{ - CloseServer(); -} - -const BOOL CCasServer::OpenServer(const WORD wServerPort) -{ - // ƒJ[ƒhƒŠ[ƒ_‘¶Ýƒ`ƒFƒbƒN - CBcasCard BCasCard; - if(!BCasCard.OpenCard())return FALSE; - - // ƒT[ƒoƒ\ƒPƒbƒgƒI[ƒvƒ“ - if(!m_pSocket.Listen(wServerPort))return FALSE; - - // ƒT[ƒoƒXƒŒƒbƒh‹N“® - pthread_create(&m_hServerThread, NULL, CCasServer::ServerThreadRaw, (LPVOID)this); - if(!m_hServerThread){ - m_pSocket.Close(); - return FALSE; - } - - return TRUE; -} - -void CCasServer::CloseServer(void) -{ - // ƒT[ƒoƒ\ƒPƒbƒgƒNƒ[ƒY - m_pSocket.Close(); - - // ƒXƒŒƒbƒhƒnƒ“ƒhƒ‹ŠJ•ú - if(m_hServerThread){ - pthread_join(m_hServerThread, NULL); - m_hServerThread = NULL; - } - - // ‘SƒNƒ‰ƒCƒAƒ“ƒgØ’f - m_Lock.Lock(); - - for(ClientList::iterator It = m_ClientList.begin() ; It != m_ClientList.end() ; It++){ - It->first->CloseClient(); - } - - m_Lock.Unlock(); - - // ‘SƒNƒ‰ƒCƒAƒ“ƒg‚̏I—¹‚ð‘Ò‚Â - while(m_ClientList.size()) sleep(1UL); -} - -const DWORD CCasServer::GetClientNum(void) const -{ - // Ú‘±’†‚̃Nƒ‰ƒCƒAƒ“ƒg”‚ð•Ô‚· - return m_ClientList.size(); -} - -void CCasServer::OnCasClientEvent(CCasClient *pClient, const DWORD dwEventID, PVOID pParam) -{ - CBlockLock AutoLock(&m_Lock); - - // ƒNƒ‰ƒCƒAƒ“ƒgƒCƒxƒ“ƒg - switch(dwEventID){ - case CCasClient::EID_CONNECTED : - // ƒŠƒXƒg‚ɒljÁ - m_ClientList[pClient] = pClient; - if (m_pEventHandler) m_pEventHandler->OnCasServerEvent(this, CSEI_CONNECTED); - break; - - case CCasClient::EID_DISCONNECTED : - // ƒŠƒXƒg‚©‚çíœ - m_ClientList.erase(pClient); - if (m_pEventHandler) m_pEventHandler->OnCasServerEvent(this, CSEI_DISCONNECTED); - break; - } -} - -void CCasServer::ServerThread(void) -{ - // ƒAƒNƒZƒvƒgƒ‹[ƒv - CSmartSock *pNewSocket; - - while(pNewSocket = m_pSocket.Accept()){ - // ƒNƒ‰ƒCƒAƒ“ƒgƒCƒ“ƒXƒ^ƒ“ƒX¶¬ - new CCasClient(this, pNewSocket); - } -} - -void* CCasServer::ServerThreadRaw(LPVOID pParam) -{ - // ƒT[ƒoƒXƒŒƒbƒh - static_cast(pParam)->ServerThread(); - - return 0UL; -} +#define TRUE 1 + +CCasServer::CCasServer(ICasServerHandler *pEventHandler) + : m_pEventHandler(pEventHandler) + , m_hServerThread(NULL) +{ + +} + +CCasServer::~CCasServer(void) +{ + CloseServer(); +} + +const BOOL CCasServer::OpenServer(const WORD wServerPort) +{ + // カードリーダ存在チェック + CBcasCard BCasCard; + if(!BCasCard.OpenCard())return FALSE; + + // サーバソケットオープン + if(!m_pSocket.Listen(wServerPort))return FALSE; + + // サーバスレッド起動 + pthread_create(&m_hServerThread, NULL, CCasServer::ServerThreadRaw, (LPVOID)this); + if(!m_hServerThread){ + m_pSocket.Close(); + return FALSE; + } + + return TRUE; +} + +void CCasServer::CloseServer(void) +{ + // サーバソケットクローズ + m_pSocket.Close(); + + // スレッドハンドル開放 + if(m_hServerThread){ + pthread_join(m_hServerThread, NULL); + m_hServerThread = NULL; + } + + // 全クライアント切断 + m_Lock.Lock(); + + for(ClientList::iterator It = m_ClientList.begin() ; It != m_ClientList.end() ; It++){ + It->first->CloseClient(); + } + + m_Lock.Unlock(); + + // 全クライアントの終了を待つ + while(m_ClientList.size()) sleep(1UL); +} + +const DWORD CCasServer::GetClientNum(void) const +{ + // 接続中のクライアント数を返す + return m_ClientList.size(); +} + +void CCasServer::OnCasClientEvent(CCasClient *pClient, const DWORD dwEventID, PVOID pParam) +{ + CBlockLock AutoLock(&m_Lock); + + // クライアントイベント + switch(dwEventID){ + case CCasClient::EID_CONNECTED : + // リストに追加 + m_ClientList[pClient] = pClient; + if (m_pEventHandler) m_pEventHandler->OnCasServerEvent(this, CSEI_CONNECTED); + break; + + case CCasClient::EID_DISCONNECTED : + // リストから削除 + m_ClientList.erase(pClient); + if (m_pEventHandler) m_pEventHandler->OnCasServerEvent(this, CSEI_DISCONNECTED); + break; + } +} + +void CCasServer::ServerThread(void) +{ + // アクセプトループ + CSmartSock *pNewSocket; + + while(pNewSocket = m_pSocket.Accept()){ + // クライアントインスタンス生成 + new CCasClient(this, pNewSocket); + } +} + +void* CCasServer::ServerThreadRaw(LPVOID pParam) +{ + // サーバスレッド + static_cast(pParam)->ServerThread(); + + return 0UL; +} diff --git a/b25-remote/CasServer.h b/b25-remote/CasServer.h index 35d7732..3757d68 100755 --- a/b25-remote/CasServer.h +++ b/b25-remote/CasServer.h @@ -1,56 +1,56 @@ -// CasServer.h: CCasServer ƒNƒ‰ƒX‚̃Cƒ“ƒ^[ƒtƒFƒCƒX -// -////////////////////////////////////////////////////////////////////// - -#pragma once - - -#include -#include "CasClient.h" -#include "TsUtilClass.h" -#include "SmartSock.h" - - -using std::map; - - -class CCasServer : protected CCasClient::ICasClientHandler -{ -public: - class ICasServerHandler - { - public: - virtual void OnCasServerEvent(CCasServer *pCasServer, const WORD wEventID) = 0; - }; - - enum - { - CSEI_CONNECTED, // ƒNƒ‰ƒCƒAƒ“ƒgÚ‘± - CSEI_DISCONNECTED, // ƒNƒ‰ƒCƒAƒ“ƒgØ’f - }; - - CCasServer(void); - CCasServer(ICasServerHandler *pEventHandler); - ~CCasServer(void); - - const BOOL OpenServer(const WORD wServerPort); - void CloseServer(void); - - const DWORD GetClientNum(void) const; - -protected: - virtual void OnCasClientEvent(CCasClient *pClient, const DWORD dwEventID, PVOID pParam); - - void ServerThread(void); - static void* ServerThreadRaw(LPVOID pParam); - - ICasServerHandler *m_pEventHandler; - - CSmartSock m_pSocket; +// CasServer.h: CCasServer クラスのインターフェイス +// +////////////////////////////////////////////////////////////////////// + +#pragma once + + +#include +#include "CasClient.h" +#include "TsUtilClass.h" +#include "SmartSock.h" + + +using std::map; + + +class CCasServer : protected CCasClient::ICasClientHandler +{ +public: + class ICasServerHandler + { + public: + virtual void OnCasServerEvent(CCasServer *pCasServer, const WORD wEventID) = 0; + }; + + enum + { + CSEI_CONNECTED, // クライアント接続 + CSEI_DISCONNECTED, // クライアント切断 + }; + + CCasServer(void); + CCasServer(ICasServerHandler *pEventHandler); + ~CCasServer(void); + + const BOOL OpenServer(const WORD wServerPort); + void CloseServer(void); + + const DWORD GetClientNum(void) const; + +protected: + virtual void OnCasClientEvent(CCasClient *pClient, const DWORD dwEventID, PVOID pParam); + + void ServerThread(void); + static void* ServerThreadRaw(LPVOID pParam); + + ICasServerHandler *m_pEventHandler; + + CSmartSock m_pSocket; pthread_t m_hServerThread; - - typedef map ClientList; - ClientList m_ClientList; - - CCriticalLock m_Lock; -}; + + typedef map ClientList; + ClientList m_ClientList; + + CCriticalLock m_Lock; +}; diff --git a/b25-remote/Readme.txt b/b25-remote/Readme.txt index 0f591d0..3887355 100755 --- a/b25-remote/Readme.txt +++ b/b25-remote/Readme.txt @@ -1,5 +1,5 @@ -- b25-remote Ver.0.0.1 - +− b25-remote Ver.0.0.1 − 1.概要 @@ -40,8 +40,8 @@   ③このとき環境変数を以下のように設定します。    LD_PRELOAD = {b25-client.soの絶対パス} -   B25_REMOTE_IP = {サーバーのアドレス(DNS可)} -   B25_REMOTE_PORT = {サーバーの使用ポート(デフォルト:6900)} +   B25_SERVER_IP = {サーバーのアドレス(DNS可)} +   B25_SERVER_PORT = {サーバーの使用ポート(デフォルト:6900)}    ※ファイヤウォールやフィルタリングを使用している場合は共有に使用するポートを開放してください。 diff --git a/b25-remote/SmartSock.cpp b/b25-remote/SmartSock.cpp index cbf802c..c26d33c 100755 --- a/b25-remote/SmartSock.cpp +++ b/b25-remote/SmartSock.cpp @@ -1,572 +1,578 @@ -// SmartSock.cpp: CSmartSock ƒNƒ‰ƒX‚̃Cƒ“ƒvƒŠƒƒ“ƒe[ƒVƒ‡ƒ“ -// -////////////////////////////////////////////////////////////////////// - -#include "SmartSock.h" +// SmartSock.cpp: CSmartSock クラスのインプリメンテーション +// +////////////////////////////////////////////////////////////////////// + +#include "SmartSock.h" #include -#include - -#ifdef _DEBUG -#define new DEBUG_NEW -#endif - -//#pragma warning(disable: 4101) // warning C4101: "ƒ[ƒJƒ‹•Ï”‚Í 1 “x‚àŽg‚í‚ê‚Ä‚¢‚Ü‚¹‚ñB" -//#pragma warning(disable: 4996) // warning C4996: "This function or variable may be unsafe. Consider using _wsplitpath_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details" - - -//#pragma comment(lib, "WS2_32") - - -////////////////////////////////////////////////////////////////////// -// ƒ}ƒNƒ’è‹` -////////////////////////////////////////////////////////////////////// - -#define CHECK_FREESOCK(R) if(m_Socket != INVALID_SOCKET){m_dwLastError = EC_SOCKINVALID; return (R);} -#define CHECK_TCPSOCK(R) if((m_Socket == INVALID_SOCKET) || (m_bSockType != SOCKTYPE_TCP)){m_dwLastError = EC_SOCKINVALID; return (R);} -#define CHECK_UDPSOCK(R) if((m_Socket == INVALID_SOCKET) || (m_bSockType != SOCKTYPE_UDP)){m_dwLastError = EC_SOCKINVALID; return (R);} - - -////////////////////////////////////////////////////////////////////// -// \’z/Á–Å -////////////////////////////////////////////////////////////////////// - -DWORD CSmartSock::dwInstanceNum = 0UL; - -CSmartSock::CSmartSock() - : m_Socket(INVALID_SOCKET) - , m_bSockType(SOCKTYPE_NON) - , m_dwLastError(EC_NOERROR) -{ - // WinSock2‰Šú‰» - if(!(dwInstanceNum++))InitWinSock2(); -} - -CSmartSock::~CSmartSock() -{ - Close(); - - // WinSock2ŠJ•ú - if(!(--dwInstanceNum))FreeWinSock2(); -} - -const BOOL CSmartSock::Connect(LPCTSTR lpszHost, const WORD wPort, const DWORD dwTimeOut) -{ - CHECK_FREESOCK(FALSE); - - if(!lpszHost){ - m_dwLastError = EC_PARAMINVALID; - return FALSE; - } - - // ƒAƒhƒŒƒX–¼‚©‚çIPƒAƒhƒŒƒXŽæ“¾ - const DWORD dwIP = HostToIP(lpszHost); - - if(dwIP == INADDR_NONE){ - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - return Connect(dwIP, wPort, dwTimeOut); -} - -const BOOL CSmartSock::Connect(const DWORD dwIP, const WORD wPort, const DWORD dwTimeOut) -{ - CHECK_FREESOCK(FALSE); - - // ƒ\ƒPƒbƒgì¬ - if((m_Socket = ::socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){ - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - // ƒAƒhƒŒƒXÝ’è - SOCKADDR_IN SockAddr; - SockAddr.sin_family = AF_INET; - SockAddr.sin_port = htons(wPort); - SockAddr.sin_addr.s_addr = htonl(dwIP); - - // “¯ŠúƒRƒlƒNƒg - if(!dwTimeOut){ - if(::connect(m_Socket, (PSOCKADDR)&SockAddr, sizeof(sockaddr))){ - Close(); - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - m_dwLastError = EC_NOERROR; - return TRUE; - } - - // ”ñ“¯ŠúƒRƒlƒNƒg - u_long nArg; - fd_set FdSet; - struct timeval TimeVal; - TimeVal.tv_sec = 10UL; +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +//#pragma warning(disable: 4101) // warning C4101: "ローカル変数は 1 度も使われていません。" +//#pragma warning(disable: 4996) // warning C4996: "This function or variable may be unsafe. Consider using _wsplitpath_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details" + + +//#pragma comment(lib, "WS2_32") + + +////////////////////////////////////////////////////////////////////// +// マクロ定義 +////////////////////////////////////////////////////////////////////// + +#define CHECK_FREESOCK(R) if(m_Socket != INVALID_SOCKET){m_dwLastError = EC_SOCKINVALID; return (R);} +#define CHECK_TCPSOCK(R) if((m_Socket == INVALID_SOCKET) || (m_bSockType != SOCKTYPE_TCP)){m_dwLastError = EC_SOCKINVALID; return (R);} +#define CHECK_UDPSOCK(R) if((m_Socket == INVALID_SOCKET) || (m_bSockType != SOCKTYPE_UDP)){m_dwLastError = EC_SOCKINVALID; return (R);} + + +////////////////////////////////////////////////////////////////////// +// 構築/消滅 +////////////////////////////////////////////////////////////////////// + +DWORD CSmartSock::dwInstanceNum = 0UL; + +CSmartSock::CSmartSock() + : m_Socket(INVALID_SOCKET) + , m_bSockType(SOCKTYPE_NON) + , m_dwLastError(EC_NOERROR) +{ + // WinSock2初期化 + if(!(dwInstanceNum++))InitWinSock2(); +} + +CSmartSock::~CSmartSock() +{ + Close(); + + // WinSock2開放 + if(!(--dwInstanceNum))FreeWinSock2(); +} + +const BOOL CSmartSock::Connect(LPCTSTR lpszHost, const WORD wPort, const DWORD dwTimeOut) +{ + CHECK_FREESOCK(FALSE); + + if(!lpszHost){ + m_dwLastError = EC_PARAMINVALID; + return FALSE; + } + + // アドレス名からIPアドレス取得 + const DWORD dwIP = HostToIP(lpszHost); + + if(dwIP == INADDR_NONE){ + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + return Connect(dwIP, wPort, dwTimeOut); +} + +const BOOL CSmartSock::Connect(const DWORD dwIP, const WORD wPort, const DWORD dwTimeOut) +{ + CHECK_FREESOCK(FALSE); + + // ソケット作成 + if((m_Socket = ::socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){ + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + // アドレス設定 + SOCKADDR_IN SockAddr; + SockAddr.sin_family = AF_INET; + SockAddr.sin_port = htons(wPort); + SockAddr.sin_addr.s_addr = htonl(dwIP); + + // 同期コネクト + if(!dwTimeOut){ + if(::connect(m_Socket, (PSOCKADDR)&SockAddr, sizeof(sockaddr))){ + Close(); + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + m_dwLastError = EC_NOERROR; + return TRUE; + } + + // 非同期コネクト + u_long nArg; + fd_set FdSet; + struct timeval TimeVal; + TimeVal.tv_sec = 10UL; TimeVal.tv_usec = 0UL; - nArg = fcntl(m_Socket, F_GETFL, 0); - FD_ZERO(&FdSet); - FD_SET(m_Socket, &FdSet); - - try{ - // ”ñ“¯Šú‚ɐ؂è‘Ö‚¦ - if(::fcntl(m_Socket, F_SETFL, nArg | O_NONBLOCK) == SOCKET_ERROR)throw (const DWORD)__LINE__; - - // ƒRƒlƒNƒg - if(::connect(m_Socket, (PSOCKADDR)&SockAddr, sizeof(sockaddr)) != SOCKET_ERROR)throw (const DWORD)__LINE__; - - if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINPROGRESS)throw (const DWORD)__LINE__; - - // Ú‘±Š®—¹‘Ò‚¿ - if(!::select(32, NULL, &FdSet, NULL, &TimeVal))throw (const DWORD)__LINE__; - - // ƒ^ƒCƒ€ƒAƒEƒg”»’è - if(!FD_ISSET(m_Socket, &FdSet)){ - Close(); - m_dwLastError = EC_TIMEOUT; - return FALSE; - } - - // “¯Šú‚ɐ؂è‘Ö‚¦ - if(::fcntl(m_Socket, F_SETFL, nArg) == SOCKET_ERROR)throw (const DWORD)__LINE__; - } - catch(const DWORD dwLine){ - // ƒGƒ‰[”­¶ - Close(); - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - m_bSockType = SOCKTYPE_TCP; - m_dwLastError = EC_NOERROR; - - return TRUE; -} - -const BOOL CSmartSock::Listen(const WORD wPort) -{ - CHECK_FREESOCK(FALSE); - - // ƒ\ƒPƒbƒgì¬ - if((m_Socket = ::socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){ - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - // ƒAƒhƒŒƒXÝ’è - SOCKADDR_IN SockAddr; - SockAddr.sin_family = AF_INET; - SockAddr.sin_port = htons(wPort); - SockAddr.sin_addr.s_addr = INADDR_ANY; - - try{ - // uƒAƒhƒŒƒXŽg—p’†vƒGƒ‰[‚ð‰ñ”ð + nArg = fcntl(m_Socket, F_GETFL, 0); + FD_ZERO(&FdSet); + FD_SET(m_Socket, &FdSet); + + try{ + // 非同期に切り替え + if(::fcntl(m_Socket, F_SETFL, nArg | O_NONBLOCK) == SOCKET_ERROR)throw (const DWORD)__LINE__; + + // コネクト + if(::connect(m_Socket, (PSOCKADDR)&SockAddr, sizeof(sockaddr)) != SOCKET_ERROR)throw (const DWORD)__LINE__; + + if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINPROGRESS)throw (const DWORD)__LINE__; + + // 接続完了待ち + if(!::select(32, NULL, &FdSet, NULL, &TimeVal))throw (const DWORD)__LINE__; + + // タイムアウト判定 + if(!FD_ISSET(m_Socket, &FdSet)){ + Close(); + m_dwLastError = EC_TIMEOUT; + return FALSE; + } + + // 同期に切り替え + if(::fcntl(m_Socket, F_SETFL, nArg) == SOCKET_ERROR)throw (const DWORD)__LINE__; + } + catch(const DWORD dwLine){ + // エラー発生 + Close(); + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + m_bSockType = SOCKTYPE_TCP; + m_dwLastError = EC_NOERROR; + + return TRUE; +} + +const BOOL CSmartSock::Listen(const WORD wPort) +{ + CHECK_FREESOCK(FALSE); + + // ソケット作成 + if((m_Socket = ::socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){ + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + // アドレス設定 + SOCKADDR_IN SockAddr; + SockAddr.sin_family = AF_INET; + SockAddr.sin_port = htons(wPort); + SockAddr.sin_addr.s_addr = INADDR_ANY; + + try{ + // 「アドレス使用中」エラーを回避 int on = 1; setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - // ƒoƒCƒ“ƒh - if(::bind(m_Socket, (PSOCKADDR)&SockAddr, sizeof(SockAddr)) == SOCKET_ERROR)throw (const DWORD)__LINE__; - - // Ú‘±Žó‚¯“ü‚ê - if(::listen(m_Socket, 5) == SOCKET_ERROR)throw (const DWORD)__LINE__; - } - catch(const DWORD dwLine){ - // ƒGƒ‰[”­¶ - Close(); - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - m_bSockType = SOCKTYPE_TCP; - m_dwLastError = EC_NOERROR; - - return TRUE; -} - -CSmartSock * CSmartSock::Accept(void) -{ - CHECK_TCPSOCK(FALSE); - - SOCKADDR_IN AddrIn; - memset(&AddrIn, 0, sizeof(AddrIn)); - socklen_t iAddrLen = sizeof(AddrIn); - - // ƒRƒlƒNƒgŽó‚¯“ü‚ê - SOCKET SockIn = ::accept(m_Socket, (sockaddr *)&AddrIn, &iAddrLen); - - if(SockIn == INVALID_SOCKET){ - Close(); - m_dwLastError = EC_SOCKERROR; - return NULL; - } - - CSmartSock *pNewSock = new CSmartSock; - pNewSock->m_Socket = SockIn; - pNewSock->m_bSockType = SOCKTYPE_TCP; - - m_dwLastError = EC_NOERROR; - - return pNewSock; -} - -const BOOL CSmartSock::Send(const BYTE *pBuff, const DWORD dwLen, const DWORD dwTimeOut) -{ - CHECK_TCPSOCK(FALSE); - - if(!pBuff || !dwLen){ - m_dwLastError = EC_PARAMINVALID; - return FALSE; - } - - // Žw’èƒTƒCƒY‘—M - DWORD dwRef = 0UL, dwSend = 0UL; - + // バインド + if(::bind(m_Socket, (PSOCKADDR)&SockAddr, sizeof(SockAddr)) == SOCKET_ERROR)throw (const DWORD)__LINE__; + + // 接続受け入れ + if(::listen(m_Socket, 5) == SOCKET_ERROR)throw (const DWORD)__LINE__; + } + catch(const DWORD dwLine){ + // エラー発生 + Close(); + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + m_bSockType = SOCKTYPE_TCP; + m_dwLastError = EC_NOERROR; + + return TRUE; +} + +CSmartSock * CSmartSock::Accept(void) +{ + CHECK_TCPSOCK(FALSE); + + SOCKADDR_IN AddrIn; + memset(&AddrIn, 0, sizeof(AddrIn)); + socklen_t iAddrLen = sizeof(AddrIn); + + // コネクト受け入れ + SOCKET SockIn = ::accept(m_Socket, (sockaddr *)&AddrIn, &iAddrLen); + + if(SockIn == INVALID_SOCKET){ + Close(); + m_dwLastError = EC_SOCKERROR; + return NULL; + } + + CSmartSock *pNewSock = new CSmartSock; + pNewSock->m_Socket = SockIn; + pNewSock->m_bSockType = SOCKTYPE_TCP; + + m_dwLastError = EC_NOERROR; + + return pNewSock; +} + +const BOOL CSmartSock::Send(const BYTE *pBuff, const DWORD dwLen, const DWORD dwTimeOut) +{ + CHECK_TCPSOCK(FALSE); + + if(!pBuff || !dwLen){ + m_dwLastError = EC_PARAMINVALID; + return FALSE; + } + + // 指定サイズ送信 + DWORD dwRef = 0UL, dwSend = 0UL; + do{ dwRef = SendOnce(pBuff + dwSend, dwLen - dwSend, dwTimeOut); - if(!dwRef) return FALSE; - } - while((dwSend += dwRef) < dwLen); - - return TRUE; -} - -const BOOL CSmartSock::Recv(BYTE *pBuff, const DWORD dwLen, const DWORD dwTimeOut) -{ - CHECK_TCPSOCK(FALSE); - - if(!pBuff || !dwLen){ - m_dwLastError = EC_PARAMINVALID; - return FALSE; - } - - // Žw’èƒTƒCƒYŽóM - DWORD dwRef = 0UL, dwRecv = 0UL; - - do{ - if(!(dwRef = RecvOnce(pBuff + dwRecv, dwLen - dwRecv, dwTimeOut)))return FALSE; - } + if(!dwRef) return FALSE; + } + while((dwSend += dwRef) < dwLen); + + return TRUE; +} + +const BOOL CSmartSock::Recv(BYTE *pBuff, const DWORD dwLen, const DWORD dwTimeOut) +{ + CHECK_TCPSOCK(FALSE); + + if(!pBuff || !dwLen){ + m_dwLastError = EC_PARAMINVALID; + return FALSE; + } + + // 指定サイズ受信 + DWORD dwRef = 0UL, dwRecv = 0UL; + + do{ + if(!(dwRef = RecvOnce(pBuff + dwRecv, dwLen - dwRecv, dwTimeOut)))return FALSE; + } while((dwRecv += dwRef) < dwLen); - - return TRUE; -} - -const DWORD CSmartSock::SendOnce(const BYTE *pBuff, const DWORD dwMaxLen, const DWORD dwTimeOut) -{ - CHECK_TCPSOCK(0UL); - - if(!pBuff || !dwMaxLen){ - m_dwLastError = EC_PARAMINVALID; - return FALSE; - } - - // ƒ^ƒCƒ€ƒAƒEƒgÝ’è - struct timeval stTimeOut; - + + return TRUE; +} + +const DWORD CSmartSock::SendOnce(const BYTE *pBuff, const DWORD dwMaxLen, const DWORD dwTimeOut) +{ + CHECK_TCPSOCK(0UL); + + if(!pBuff || !dwMaxLen){ + m_dwLastError = EC_PARAMINVALID; + return FALSE; + } + + // タイムアウト設定 + struct timeval stTimeOut; + stTimeOut.tv_sec = 10UL; - stTimeOut.tv_usec = 0UL; - if(::setsockopt(m_Socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&stTimeOut, sizeof(struct timeval))){ - Close(); + stTimeOut.tv_usec = 0UL; + if(::setsockopt(m_Socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&stTimeOut, sizeof(struct timeval))){ + Close(); m_dwLastError = EC_SOCKERROR; - return 0UL; - } - - // ‘—M - const int iRef = ::send(m_Socket, (const char *)pBuff, dwMaxLen, 0); - - if((iRef == SOCKET_ERROR) || !iRef){ - if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS){ - m_dwLastError = EC_TIMEOUT; - return 0UL; - } - else{ - Close(); - m_dwLastError = EC_SOCKERROR; - return 0UL; - } - } - - m_dwLastError = EC_NOERROR; - - return (DWORD)iRef; -} - -const DWORD CSmartSock::RecvOnce(BYTE *pBuff, const DWORD dwMaxLen, const DWORD dwTimeOut) -{ - CHECK_TCPSOCK(0UL); - - if(!pBuff || !dwMaxLen){ - m_dwLastError = EC_PARAMINVALID; - return FALSE; - } - - // ƒ^ƒCƒ€ƒAƒEƒg’lÝ’è - struct timeval stTimeOut; + return 0UL; + } + + // 送信 + const int iRef = ::send(m_Socket, (const char *)pBuff, dwMaxLen, 0); + + if((iRef == SOCKET_ERROR) || !iRef){ + if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS){ + m_dwLastError = EC_TIMEOUT; + return 0UL; + } + else{ + Close(); + m_dwLastError = EC_SOCKERROR; + return 0UL; + } + } + + m_dwLastError = EC_NOERROR; + + return (DWORD)iRef; +} + +const DWORD CSmartSock::RecvOnce(BYTE *pBuff, const DWORD dwMaxLen, const DWORD dwTimeOut) +{ + CHECK_TCPSOCK(0UL); + + if(!pBuff || !dwMaxLen){ + m_dwLastError = EC_PARAMINVALID; + return FALSE; + } + + // タイムアウト値設定 + struct timeval stTimeOut; stTimeOut.tv_sec = 10UL; - stTimeOut.tv_usec = 0UL; - if(::setsockopt(m_Socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&stTimeOut, sizeof(struct timeval))){ - Close(); + stTimeOut.tv_usec = 0UL; + if(::setsockopt(m_Socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&stTimeOut, sizeof(struct timeval))){ + Close(); m_dwLastError = EC_SOCKERROR; - return 0UL; - } + return 0UL; + } - // ŽóM - int iRef = ::recv(m_Socket, (char *)pBuff, dwMaxLen, 0); - - if((iRef == SOCKET_ERROR) || !iRef){ + // 受信 + int iRef = ::recv(m_Socket, (char *)pBuff, dwMaxLen, 0); + + if ( !iRef ) { + Close(); + m_dwLastError = EC_SOCKERROR; + return 0UL; + } + + if( iRef == SOCKET_ERROR ){ if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS){ - m_dwLastError = EC_TIMEOUT; - return 0UL; - } - else{ - Close(); - m_dwLastError = EC_SOCKERROR; - return 0UL; - } - } - - m_dwLastError = EC_NOERROR; - - return (DWORD)iRef; -} - -const BOOL CSmartSock::GetLocalAddr(DWORD *pdwIP, WORD *pwPort) -{ - CHECK_TCPSOCK(FALSE); - - struct sockaddr_in LocalAddr; - socklen_t AddrLen = sizeof(LocalAddr); - - // ƒ[ƒJƒ‹ƒAƒhƒŒƒXŽæ“¾ - if(::getsockname(m_Socket, (struct sockaddr *)&LocalAddr, &AddrLen) == SOCKET_ERROR){ - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - if(pdwIP)*pdwIP = htonl(LocalAddr.sin_addr.s_addr); - if(pwPort)*pwPort = ntohs(LocalAddr.sin_port); - - m_dwLastError = EC_NOERROR; - - return TRUE; -} - -const BOOL CSmartSock::GetPeerAddr(DWORD *pIP, WORD *pPort) -{ - CHECK_TCPSOCK(FALSE); - - struct sockaddr_in PeerAddr; - socklen_t AddrLen = sizeof(PeerAddr); - - // ƒsƒAƒAƒhƒŒƒXŽæ“¾ - if(::getpeername(m_Socket, (struct sockaddr *)&PeerAddr, &AddrLen) == SOCKET_ERROR){ - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - if(pIP)*pIP = htonl(PeerAddr.sin_addr.s_addr); - if(pPort)*pPort = ntohs(PeerAddr.sin_port); - - m_dwLastError = EC_NOERROR; - - return TRUE; -} - -const BOOL CSmartSock::Bind() -{ - CHECK_FREESOCK(FALSE); - - // UDPƒ\ƒPƒbƒgì¬ - if((m_Socket = ::socket(PF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET){ - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - // ƒAƒhƒŒƒXÝ’è - SOCKADDR_IN SockAddr; - SockAddr.sin_family = AF_INET; - SockAddr.sin_port = 0U; - SockAddr.sin_addr.s_addr = INADDR_ANY; - - // ƒoƒCƒ“ƒh - if(::bind(m_Socket, (struct sockaddr *)&SockAddr, sizeof(SockAddr)) == SOCKET_ERROR){ - Close(); - m_dwLastError = EC_SOCKERROR; - return FALSE; - } - - m_dwLastError = EC_NOERROR; - m_bSockType = SOCKTYPE_UDP; - - return TRUE; -} - -const DWORD CSmartSock::SendTo(const DWORD dwIP, const WORD wPort, const BYTE *pBuff, const DWORD dwLen) -{ - CHECK_UDPSOCK(0UL); - - if(!pBuff || !dwLen){ - m_dwLastError = EC_PARAMINVALID; - return 0UL; - } - - // ƒAƒhƒŒƒXÝ’è - SOCKADDR_IN SockAddr; - SockAddr.sin_family = AF_INET; - SockAddr.sin_port = htons(wPort); - SockAddr.sin_addr.s_addr = htonl(dwIP); - - // ‘—M - int iSend = sendto(m_Socket, (const char *)pBuff, dwLen, 0, (struct sockaddr *)&SockAddr, sizeof(SockAddr)); - - if(iSend == SOCKET_ERROR){ - m_dwLastError = EC_SOCKERROR; - return 0UL; - } - - m_dwLastError = EC_NOERROR; - - return (DWORD)iSend; -} - -const DWORD CSmartSock::SendTo(LPCTSTR lpszHost, const WORD wPort, const BYTE *pBuff, const DWORD dwLen) -{ - CHECK_UDPSOCK(0UL); - - if(!lpszHost || !pBuff || !dwLen){ - m_dwLastError = EC_PARAMINVALID; - return 0UL; - } - - // ƒAƒhƒŒƒX–¼‚©‚çIPƒAƒhƒŒƒXŽæ“¾ - const DWORD dwIP = HostToIP(lpszHost); - - if(dwIP == INADDR_NONE){ - m_dwLastError = EC_SOCKERROR; - return 0UL; - } - - return SendTo(dwIP, wPort, pBuff, dwLen); -} - -const DWORD CSmartSock::RecvFrom(BYTE *pBuff, const DWORD dwLen, DWORD *pdwIP, WORD *pwPort) -{ - CHECK_UDPSOCK(0UL); - - if(!pBuff || !dwLen){ - m_dwLastError = EC_PARAMINVALID; - return 0UL; - } - - // ƒAƒhƒŒƒXÝ’è - socklen_t iSockSize = sizeof(SOCKADDR_IN); - SOCKADDR_IN SockAddr; - SockAddr.sin_family = AF_INET; - SockAddr.sin_port = 0U; - SockAddr.sin_addr.s_addr = 0UL; - - // ŽóM - const int iRecv = ::recvfrom(m_Socket, (char *)pBuff, dwLen, 0, (struct sockaddr *)&SockAddr, &iSockSize); - - if(iRecv == SOCKET_ERROR){ - m_dwLastError = EC_SOCKERROR; - return 0UL; - } - - if(pdwIP)*pdwIP = SockAddr.sin_addr.s_addr; - if(pwPort)*pwPort = ntohs(SockAddr.sin_port); - - m_dwLastError = EC_NOERROR; - - return (DWORD)iRecv; -} - -const BOOL CSmartSock::Close() -{ - // ƒ\ƒPƒbƒgƒNƒ[ƒY - if(m_Socket != INVALID_SOCKET){ - if(m_bSockType == SOCKTYPE_TCP){ - char byData; - ::shutdown(m_Socket, SD_BOTH); - while(::recv(m_Socket, &byData, 1, 0) == 1); - } - - ::close(m_Socket); - m_Socket = INVALID_SOCKET; - } - - m_bSockType = SOCKTYPE_NON; - m_dwLastError = EC_NOERROR; - - return TRUE; -} - -const DWORD CSmartSock::HostToIP(LPCTSTR lpszHost) -{ -#ifdef _UNICODE - char szHost[1024] = {"\0"}; - ::wcstombs(szHost, lpszHost, sizeof(szHost) - 1); -#else - LPCSTR szHost = lpszHost; -#endif - - // ƒzƒXƒg–¼‚©‚çIPƒAƒhƒŒƒXŽæ“¾ - const DWORD dwIP = ::inet_addr(szHost); - - if(dwIP == INADDR_NONE){ - struct hostent *pHost = ::gethostbyname(szHost); - if(!pHost){ - return INADDR_NONE; - } - else return *((DWORD *)pHost->h_addr_list[0]); - } - else return htonl(dwIP); -} - -const DWORD CSmartSock::IPToHost(LPTSTR lpszHost, const DWORD dwIP) -{ - if(!lpszHost)return FALSE; - - // IPƒAƒhƒŒƒX‚©‚çƒzƒXƒg–¼Žæ“¾ - const DWORD dwNetIP = htonl(dwIP); - struct hostent *pHost = ::gethostbyaddr((const char *)&dwNetIP, sizeof(dwNetIP), AF_INET); - if(!pHost)return FALSE; - -#ifdef _UNICODE - ::mbstowcs(lpszHost, pHost->h_name, ::lstrlenA(pHost->h_name)); -#else - ::strcpy(lpszHost, pHost->h_name); -#endif - - return ::strlen(lpszHost); -} - -const DWORD CSmartSock::GetLastError() const -{ - // ÅŒã‚É”­¶‚µ‚½ƒGƒ‰[‚ð•Ô‚· - return m_dwLastError; -} - -const BOOL CSmartSock::InitWinSock2(void) -{ -#ifdef _UNICODE - ::setlocale(LC_ALL, "japanese"); -#endif -/* - WSADATA WsaData; - - // WinSock2‰Šú‰» - if(::WSAStartup(MAKEWORD(2, 2), &WsaData))return FALSE; - - if((LOBYTE(WsaData.wVersion) != 2U) || (HIBYTE(WsaData.wVersion) != 2U))return FALSE; -*/ - return TRUE; -} - -const BOOL CSmartSock::FreeWinSock2(void) -{ + m_dwLastError = EC_TIMEOUT; + return 0UL; + } + else{ + Close(); + m_dwLastError = EC_SOCKERROR; + return 0UL; + } + } + + m_dwLastError = EC_NOERROR; + + return (DWORD)iRef; +} + +const BOOL CSmartSock::GetLocalAddr(DWORD *pdwIP, WORD *pwPort) +{ + CHECK_TCPSOCK(FALSE); + + struct sockaddr_in LocalAddr; + socklen_t AddrLen = sizeof(LocalAddr); + + // ローカルアドレス取得 + if(::getsockname(m_Socket, (struct sockaddr *)&LocalAddr, &AddrLen) == SOCKET_ERROR){ + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + if(pdwIP)*pdwIP = htonl(LocalAddr.sin_addr.s_addr); + if(pwPort)*pwPort = ntohs(LocalAddr.sin_port); + + m_dwLastError = EC_NOERROR; + + return TRUE; +} + +const BOOL CSmartSock::GetPeerAddr(DWORD *pIP, WORD *pPort) +{ + CHECK_TCPSOCK(FALSE); + + struct sockaddr_in PeerAddr; + socklen_t AddrLen = sizeof(PeerAddr); + + // ピアアドレス取得 + if(::getpeername(m_Socket, (struct sockaddr *)&PeerAddr, &AddrLen) == SOCKET_ERROR){ + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + if(pIP)*pIP = htonl(PeerAddr.sin_addr.s_addr); + if(pPort)*pPort = ntohs(PeerAddr.sin_port); + + m_dwLastError = EC_NOERROR; + + return TRUE; +} + +const BOOL CSmartSock::Bind() +{ + CHECK_FREESOCK(FALSE); + + // UDPソケット作成 + if((m_Socket = ::socket(PF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET){ + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + // アドレス設定 + SOCKADDR_IN SockAddr; + SockAddr.sin_family = AF_INET; + SockAddr.sin_port = 0U; + SockAddr.sin_addr.s_addr = INADDR_ANY; + + // バインド + if(::bind(m_Socket, (struct sockaddr *)&SockAddr, sizeof(SockAddr)) == SOCKET_ERROR){ + Close(); + m_dwLastError = EC_SOCKERROR; + return FALSE; + } + + m_dwLastError = EC_NOERROR; + m_bSockType = SOCKTYPE_UDP; + + return TRUE; +} + +const DWORD CSmartSock::SendTo(const DWORD dwIP, const WORD wPort, const BYTE *pBuff, const DWORD dwLen) +{ + CHECK_UDPSOCK(0UL); + + if(!pBuff || !dwLen){ + m_dwLastError = EC_PARAMINVALID; + return 0UL; + } + + // アドレス設定 + SOCKADDR_IN SockAddr; + SockAddr.sin_family = AF_INET; + SockAddr.sin_port = htons(wPort); + SockAddr.sin_addr.s_addr = htonl(dwIP); + + // 送信 + int iSend = sendto(m_Socket, (const char *)pBuff, dwLen, 0, (struct sockaddr *)&SockAddr, sizeof(SockAddr)); + + if(iSend == SOCKET_ERROR){ + m_dwLastError = EC_SOCKERROR; + return 0UL; + } + + m_dwLastError = EC_NOERROR; + + return (DWORD)iSend; +} + +const DWORD CSmartSock::SendTo(LPCTSTR lpszHost, const WORD wPort, const BYTE *pBuff, const DWORD dwLen) +{ + CHECK_UDPSOCK(0UL); + + if(!lpszHost || !pBuff || !dwLen){ + m_dwLastError = EC_PARAMINVALID; + return 0UL; + } + + // アドレス名からIPアドレス取得 + const DWORD dwIP = HostToIP(lpszHost); + + if(dwIP == INADDR_NONE){ + m_dwLastError = EC_SOCKERROR; + return 0UL; + } + + return SendTo(dwIP, wPort, pBuff, dwLen); +} + +const DWORD CSmartSock::RecvFrom(BYTE *pBuff, const DWORD dwLen, DWORD *pdwIP, WORD *pwPort) +{ + CHECK_UDPSOCK(0UL); + + if(!pBuff || !dwLen){ + m_dwLastError = EC_PARAMINVALID; + return 0UL; + } + + // アドレス設定 + socklen_t iSockSize = sizeof(SOCKADDR_IN); + SOCKADDR_IN SockAddr; + SockAddr.sin_family = AF_INET; + SockAddr.sin_port = 0U; + SockAddr.sin_addr.s_addr = 0UL; + + // 受信 + const int iRecv = ::recvfrom(m_Socket, (char *)pBuff, dwLen, 0, (struct sockaddr *)&SockAddr, &iSockSize); + + if(iRecv == SOCKET_ERROR){ + m_dwLastError = EC_SOCKERROR; + return 0UL; + } + + if(pdwIP)*pdwIP = SockAddr.sin_addr.s_addr; + if(pwPort)*pwPort = ntohs(SockAddr.sin_port); + + m_dwLastError = EC_NOERROR; + + return (DWORD)iRecv; +} + +const BOOL CSmartSock::Close() +{ + // ソケットクローズ + if(m_Socket != INVALID_SOCKET){ + if(m_bSockType == SOCKTYPE_TCP){ + char byData; + ::shutdown(m_Socket, SD_BOTH); + while(::recv(m_Socket, &byData, 1, 0) == 1); + } + + ::close(m_Socket); + m_Socket = INVALID_SOCKET; + } + + m_bSockType = SOCKTYPE_NON; + m_dwLastError = EC_NOERROR; + + return TRUE; +} + +const DWORD CSmartSock::HostToIP(LPCTSTR lpszHost) +{ +#ifdef _UNICODE + char szHost[1024] = {"\0"}; + ::wcstombs(szHost, lpszHost, sizeof(szHost) - 1); +#else + LPCSTR szHost = lpszHost; +#endif + + // ホスト名からIPアドレス取得 + const DWORD dwIP = ::inet_addr(szHost); + + if(dwIP == INADDR_NONE){ + struct hostent *pHost = ::gethostbyname(szHost); + if(!pHost){ + return INADDR_NONE; + } + else return *((DWORD *)pHost->h_addr_list[0]); + } + else return htonl(dwIP); +} + +const DWORD CSmartSock::IPToHost(LPTSTR lpszHost, const DWORD dwIP) +{ + if(!lpszHost)return FALSE; + + // IPアドレスからホスト名取得 + const DWORD dwNetIP = htonl(dwIP); + struct hostent *pHost = ::gethostbyaddr((const char *)&dwNetIP, sizeof(dwNetIP), AF_INET); + if(!pHost)return FALSE; + +#ifdef _UNICODE + ::mbstowcs(lpszHost, pHost->h_name, ::lstrlenA(pHost->h_name)); +#else + ::strcpy(lpszHost, pHost->h_name); +#endif + + return ::strlen(lpszHost); +} + +const DWORD CSmartSock::GetLastError() const +{ + // 最後に発生したエラーを返す + return m_dwLastError; +} + +const BOOL CSmartSock::InitWinSock2(void) +{ +#ifdef _UNICODE + ::setlocale(LC_ALL, "japanese"); +#endif +/* + WSADATA WsaData; + + // WinSock2初期化 + if(::WSAStartup(MAKEWORD(2, 2), &WsaData))return FALSE; + + if((LOBYTE(WsaData.wVersion) != 2U) || (HIBYTE(WsaData.wVersion) != 2U))return FALSE; +*/ + return TRUE; +} + +const BOOL CSmartSock::FreeWinSock2(void) +{ /* - // WinSock2ŠJ•ú - return (::WSACleanup())? TRUE : FALSE; + // WinSock2開放 + return (::WSACleanup())? TRUE : FALSE; */ return TRUE; -} +} diff --git a/b25-remote/SmartSock.h b/b25-remote/SmartSock.h index d735339..057e7b3 100755 --- a/b25-remote/SmartSock.h +++ b/b25-remote/SmartSock.h @@ -1,17 +1,17 @@ -// SmartSock.h: CSmartSock ƒNƒ‰ƒX‚̃Cƒ“ƒ^[ƒtƒFƒCƒX -// -////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "W2L.h" +// SmartSock.h: CSmartSock クラスのインターフェイス +// +////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "W2L.h" #include #include #include #include #include #include - + #define BOOL bool #define LPTSTR char* #define LPCTSTR const char* @@ -20,60 +20,60 @@ #define WORD unsigned short #define DWORD unsigned long #define SOCKET int - -// WinSock2ƒ^ƒCƒ€ƒAƒEƒg‘Ήžƒ‰ƒbƒp[ƒNƒ‰ƒX http://2sen.dip.jp/friio/ -class CSmartSock -{ -public: - enum // LastErrorƒR[ƒh - { - EC_NOERROR, // ³íI—¹ - EC_SOCKERROR, // ƒ\ƒPƒbƒgƒGƒ‰[ - EC_TIMEOUT, // ƒ^ƒCƒ€ƒAƒEƒg - EC_SOCKINVALID, // ƒ\ƒPƒbƒg‚ª–³Œø - EC_PARAMINVALID // ƒpƒ‰ƒ[ƒ^‚ª–³Œø - }; - - CSmartSock(); - virtual ~CSmartSock(); - -// TCPƒ\ƒPƒbƒg - const BOOL Connect(LPCTSTR lpszHost, const WORD wPort, const DWORD dwTimeOut = 0UL); - const BOOL Connect(const DWORD dwIP, const WORD wPort, const DWORD dwTimeOut = 0UL); - - const BOOL Listen(const WORD wPort); - CSmartSock * Accept(void); - - const BOOL Send(const BYTE *pBuff, const DWORD dwLen, const DWORD dwTimeOut = 0UL); - const BOOL Recv(BYTE *pBuff, const DWORD dwLen, const DWORD dwTimeOut = 0UL); - const DWORD SendOnce(const BYTE *pBuff, const DWORD dwMaxLen, const DWORD dwTimeOut = 0UL); - const DWORD RecvOnce(BYTE *pBuff, const DWORD dwMaxLen, const DWORD dwTimeOut = 0UL); - - const BOOL GetLocalAddr(DWORD *pdwIP, WORD *pwPort = NULL); - const BOOL GetPeerAddr(DWORD *pdwIP, WORD *pwPort = NULL); - -// UDPƒ\ƒPƒbƒg - const BOOL Bind(void); - - const DWORD SendTo(const DWORD dwIP, const WORD wPort, const BYTE *pBuff, const DWORD dwLen); - const DWORD SendTo(LPCTSTR lpszHost, const WORD wPort, const BYTE *pBuff, const DWORD dwLen); - const DWORD RecvFrom(BYTE *pBuff, const DWORD dwLen, DWORD *pdwIP = NULL, WORD *pwPort = NULL); - - const BOOL Close(void); - - static const DWORD HostToIP(LPCTSTR lpszHost); - static const DWORD IPToHost(LPTSTR lpszHost, const DWORD dwIP); - - const DWORD GetLastError(void) const; - -protected: - static const BOOL InitWinSock2(void); - static const BOOL FreeWinSock2(void); - - enum {SOCKTYPE_NON, SOCKTYPE_TCP, SOCKTYPE_UDP}; - - int m_Socket; // ƒ\ƒPƒbƒgƒnƒ“ƒhƒ‹ - BYTE m_bSockType; // ƒ\ƒPƒbƒgƒ^ƒCƒv - DWORD m_dwLastError; // ÅIƒGƒ‰[ƒR[ƒh - static DWORD dwInstanceNum; // ƒCƒ“ƒXƒ^ƒ“ƒX‚̐” -}; + +// WinSock2タイムアウト対応ラッパークラス http://2sen.dip.jp/friio/ +class CSmartSock +{ +public: + enum // LastErrorコード + { + EC_NOERROR, // 正常終了 + EC_SOCKERROR, // ソケットエラー + EC_TIMEOUT, // タイムアウト + EC_SOCKINVALID, // ソケットが無効 + EC_PARAMINVALID // パラメータが無効 + }; + + CSmartSock(); + virtual ~CSmartSock(); + +// TCPソケット + const BOOL Connect(LPCTSTR lpszHost, const WORD wPort, const DWORD dwTimeOut = 0UL); + const BOOL Connect(const DWORD dwIP, const WORD wPort, const DWORD dwTimeOut = 0UL); + + const BOOL Listen(const WORD wPort); + CSmartSock * Accept(void); + + const BOOL Send(const BYTE *pBuff, const DWORD dwLen, const DWORD dwTimeOut = 0UL); + const BOOL Recv(BYTE *pBuff, const DWORD dwLen, const DWORD dwTimeOut = 0UL); + const DWORD SendOnce(const BYTE *pBuff, const DWORD dwMaxLen, const DWORD dwTimeOut = 0UL); + const DWORD RecvOnce(BYTE *pBuff, const DWORD dwMaxLen, const DWORD dwTimeOut = 0UL); + + const BOOL GetLocalAddr(DWORD *pdwIP, WORD *pwPort = NULL); + const BOOL GetPeerAddr(DWORD *pdwIP, WORD *pwPort = NULL); + +// UDPソケット + const BOOL Bind(void); + + const DWORD SendTo(const DWORD dwIP, const WORD wPort, const BYTE *pBuff, const DWORD dwLen); + const DWORD SendTo(LPCTSTR lpszHost, const WORD wPort, const BYTE *pBuff, const DWORD dwLen); + const DWORD RecvFrom(BYTE *pBuff, const DWORD dwLen, DWORD *pdwIP = NULL, WORD *pwPort = NULL); + + const BOOL Close(void); + + static const DWORD HostToIP(LPCTSTR lpszHost); + static const DWORD IPToHost(LPTSTR lpszHost, const DWORD dwIP); + + const DWORD GetLastError(void) const; + +protected: + static const BOOL InitWinSock2(void); + static const BOOL FreeWinSock2(void); + + enum {SOCKTYPE_NON, SOCKTYPE_TCP, SOCKTYPE_UDP}; + + int m_Socket; // ソケットハンドル + BYTE m_bSockType; // ソケットタイプ + DWORD m_dwLastError; // 最終エラーコード + static DWORD dwInstanceNum; // インスタンスの数 +}; diff --git a/b25-remote/TsUtilClass.cpp b/b25-remote/TsUtilClass.cpp index ec4c298..9c1301f 100755 --- a/b25-remote/TsUtilClass.cpp +++ b/b25-remote/TsUtilClass.cpp @@ -1,88 +1,88 @@ -// TsUtilClass.cpp: TSƒ†[ƒeƒBƒŠƒeƒB[ƒNƒ‰ƒX‚̃Cƒ“ƒvƒŠƒƒ“ƒe[ƒVƒ‡ƒ“ -// -////////////////////////////////////////////////////////////////////// - -#include "TsUtilClass.h" - - -////////////////////////////////////////////////////////////////////// -// CDynamicReferenceable ƒNƒ‰ƒX‚̍\’z/Á–Å -////////////////////////////////////////////////////////////////////// - -CDynamicReferenceable::CDynamicReferenceable() - : m_dwRefCount(0UL) -{ - -} - -CDynamicReferenceable::~CDynamicReferenceable() -{ - -} - -void CDynamicReferenceable::AddRef(void) -{ - // ŽQÆƒJƒEƒ“ƒgƒCƒ“ƒNƒŠƒƒ“ƒg - m_dwRefCount++; -} - -void CDynamicReferenceable::ReleaseRef(void) -{ - // ŽQÆƒJƒEƒ“ƒgƒfƒNƒŠƒƒ“ƒg - if(m_dwRefCount){ - // ƒCƒ“ƒXƒ^ƒ“ƒXŠJ•ú - if(!(--m_dwRefCount))delete this; - } -#ifdef _DEBUG - else{ - ::DebugBreak(); - } -#endif -} - - -////////////////////////////////////////////////////////////////////// -// CCriticalLock ƒNƒ‰ƒX‚̍\’z/Á–Å -////////////////////////////////////////////////////////////////////// - -CCriticalLock::CCriticalLock() -{ - // ƒNƒŠƒeƒBƒJƒ‹ƒZƒNƒVƒ‡ƒ“‰Šú‰» - pthread_mutex_init(&m_CriticalSection, NULL); -} - -CCriticalLock::~CCriticalLock() -{ - // ƒNƒŠƒeƒBƒJƒ‹ƒZƒNƒVƒ‡ƒ“íœ - pthread_mutex_destroy(&m_CriticalSection); -} - -void CCriticalLock::Lock(void) -{ - // ƒNƒŠƒeƒBƒJƒ‹ƒZƒNƒVƒ‡ƒ“Žæ“¾ - pthread_mutex_lock(&m_CriticalSection); -} - -void CCriticalLock::Unlock(void) -{ - // ƒNƒŠƒeƒBƒJƒ‹ƒZƒNƒVƒ‡ƒ“ŠJ•ú - pthread_mutex_unlock(&m_CriticalSection); -} - - -////////////////////////////////////////////////////////////////////// -// CBlockLock ƒNƒ‰ƒX‚̍\’z/Á–Å -////////////////////////////////////////////////////////////////////// - -CBlockLock::CBlockLock(CCriticalLock *pCriticalLock) - : m_pCriticalLock(pCriticalLock) -{ - // ƒƒbƒNŽæ“¾ - m_pCriticalLock->Lock(); -} - -CBlockLock::~CBlockLock() -{ - // ƒƒbƒNŠJ•ú - m_pCriticalLock->Unlock(); -} +// TsUtilClass.cpp: TSユーティリティークラスのインプリメンテーション +// +////////////////////////////////////////////////////////////////////// + +#include "TsUtilClass.h" + + +////////////////////////////////////////////////////////////////////// +// CDynamicReferenceable クラスの構築/消滅 +////////////////////////////////////////////////////////////////////// + +CDynamicReferenceable::CDynamicReferenceable() + : m_dwRefCount(0UL) +{ + +} + +CDynamicReferenceable::~CDynamicReferenceable() +{ + +} + +void CDynamicReferenceable::AddRef(void) +{ + // 参照カウントインクリメント + m_dwRefCount++; +} + +void CDynamicReferenceable::ReleaseRef(void) +{ + // 参照カウントデクリメント + if(m_dwRefCount){ + // インスタンス開放 + if(!(--m_dwRefCount))delete this; + } +#ifdef _DEBUG + else{ + ::DebugBreak(); + } +#endif +} + + +////////////////////////////////////////////////////////////////////// +// CCriticalLock クラスの構築/消滅 +////////////////////////////////////////////////////////////////////// + +CCriticalLock::CCriticalLock() +{ + // クリティカルセクション初期化 + pthread_mutex_init(&m_CriticalSection, NULL); +} + +CCriticalLock::~CCriticalLock() +{ + // クリティカルセクション削除 + pthread_mutex_destroy(&m_CriticalSection); +} + +void CCriticalLock::Lock(void) +{ + // クリティカルセクション取得 + pthread_mutex_lock(&m_CriticalSection); +} + +void CCriticalLock::Unlock(void) +{ + // クリティカルセクション開放 + pthread_mutex_unlock(&m_CriticalSection); +} + + +////////////////////////////////////////////////////////////////////// +// CBlockLock クラスの構築/消滅 +////////////////////////////////////////////////////////////////////// + +CBlockLock::CBlockLock(CCriticalLock *pCriticalLock) + : m_pCriticalLock(pCriticalLock) +{ + // ロック取得 + m_pCriticalLock->Lock(); +} + +CBlockLock::~CBlockLock() +{ + // ロック開放 + m_pCriticalLock->Unlock(); +} diff --git a/b25-remote/TsUtilClass.h b/b25-remote/TsUtilClass.h index ebae86b..65cb198 100755 --- a/b25-remote/TsUtilClass.h +++ b/b25-remote/TsUtilClass.h @@ -1,61 +1,61 @@ -// TsUtilClass.h: TSƒ†[ƒeƒBƒŠƒeƒB[ƒNƒ‰ƒX‚̃Cƒ“ƒ^[ƒtƒFƒCƒX -// -////////////////////////////////////////////////////////////////////// - -#pragma once -#include "W2L.h" +// TsUtilClass.h: TSユーティリティークラスのインターフェイス +// +////////////////////////////////////////////////////////////////////// + +#pragma once +#include "W2L.h" #include - + #define DWORD unsigned long -///////////////////////////////////////////////////////////////////////////// -// ƒ_ƒCƒiƒ~ƒbƒNƒŠƒtƒ@ƒŒƒ“ƒXŠÇ—ƒx[ƒXƒNƒ‰ƒX -///////////////////////////////////////////////////////////////////////////// - -class CDynamicReferenceable -{ -public: - CDynamicReferenceable(); - virtual ~CDynamicReferenceable(); - - void AddRef(void); - void ReleaseRef(void); - -private: - DWORD m_dwRefCount; -}; - - -///////////////////////////////////////////////////////////////////////////// -// ƒNƒŠƒeƒBƒJƒ‹ƒZƒNƒVƒ‡ƒ“ƒ‰ƒbƒp[ƒNƒ‰ƒX -///////////////////////////////////////////////////////////////////////////// - -class CCriticalLock -{ -public: - CCriticalLock(); - virtual ~CCriticalLock(); - - void Lock(void); - void Unlock(void); - -private: - pthread_mutex_t m_CriticalSection; -}; - - -///////////////////////////////////////////////////////////////////////////// -// ƒuƒƒbƒNƒXƒR[ƒvƒƒbƒNƒNƒ‰ƒX -///////////////////////////////////////////////////////////////////////////// - -class CBlockLock -{ -public: - CBlockLock(CCriticalLock *pCriticalLock); - virtual ~CBlockLock(); - -private: - CCriticalLock *m_pCriticalLock; -}; - - +///////////////////////////////////////////////////////////////////////////// +// ダイナミックリファレンス管理ベースクラス +///////////////////////////////////////////////////////////////////////////// + +class CDynamicReferenceable +{ +public: + CDynamicReferenceable(); + virtual ~CDynamicReferenceable(); + + void AddRef(void); + void ReleaseRef(void); + +private: + DWORD m_dwRefCount; +}; + + +///////////////////////////////////////////////////////////////////////////// +// クリティカルセクションラッパークラス +///////////////////////////////////////////////////////////////////////////// + +class CCriticalLock +{ +public: + CCriticalLock(); + virtual ~CCriticalLock(); + + void Lock(void); + void Unlock(void); + +private: + pthread_mutex_t m_CriticalSection; +}; + + +///////////////////////////////////////////////////////////////////////////// +// ブロックスコープロッククラス +///////////////////////////////////////////////////////////////////////////// + +class CBlockLock +{ +public: + CBlockLock(CCriticalLock *pCriticalLock); + virtual ~CBlockLock(); + +private: + CCriticalLock *m_pCriticalLock; +}; + + diff --git a/b25-remote/b25-client.cpp b/b25-remote/b25-client.cpp index f108e00..bb2ee89 100755 --- a/b25-remote/b25-client.cpp +++ b/b25-remote/b25-client.cpp @@ -1,87 +1,87 @@ -// MllMain.cpp : DLL ƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚̃Gƒ“ƒgƒŠ ƒ|ƒCƒ“ƒg‚ð’è‹`‚µ‚Ü‚·B -// +// MllMain.cpp : DLL アプリケーションのエントリ ポイントを定義します。 +// #include -#include -#include "CasProxy.h" -#include "W2L.h" +#include +#include "CasProxy.h" +#include "W2L.h" #ifndef SCARD_AUTOALLOCATE #define SCARD_AUTOALLOCATE (DWORD)(-1) /**< see SCardFreeMemory() */ -#endif - -////////////////////////////////////////////////////////////////////// -// WinSCardƒtƒbƒN -////////////////////////////////////////////////////////////////////// -LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) -{ - // ƒvƒƒLƒVƒCƒ“ƒXƒ^ƒ“ƒX¶¬ - CCasProxy *pCasProxy = new CCasProxy(); - - // ƒT[ƒo‚ɐڑ± - if(!pCasProxy->Connect()){ - delete pCasProxy; - *phCard = NULL; - return SCARD_E_READER_UNAVAILABLE; +#endif + +////////////////////////////////////////////////////////////////////// +// WinSCardフック +////////////////////////////////////////////////////////////////////// +LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) +{ + // プロキシインスタンス生成 + CCasProxy *pCasProxy = new CCasProxy(); + + // サーバに接続 + if(!pCasProxy->Connect()){ + delete pCasProxy; + *phCard = NULL; + return SCARD_E_READER_UNAVAILABLE; } - - // ƒnƒ“ƒhƒ‹‚É–„‚ߍž‚Þ - *phCard = reinterpret_cast(pCasProxy); - if(pdwActiveProtocol)*pdwActiveProtocol = SCARD_PROTOCOL_T1; - - return SCARD_S_SUCCESS; -} - -LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) -{ - // ƒT[ƒo‚©‚çØ’f - CCasProxy *pCasProxy = reinterpret_cast(hCard); - if(pCasProxy)delete pCasProxy; - - return SCARD_S_SUCCESS; -} - -LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) + + // ハンドルに埋め込む + *phCard = reinterpret_cast(pCasProxy); + if(pdwActiveProtocol)*pdwActiveProtocol = SCARD_PROTOCOL_T1; + + return SCARD_S_SUCCESS; +} + +LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) +{ + // サーバから切断 + CCasProxy *pCasProxy = reinterpret_cast(hCard); + if(pCasProxy)delete pCasProxy; + + return SCARD_S_SUCCESS; +} + +LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) +{ + return SCARD_S_SUCCESS; +} + +LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) +{ + return SCARD_S_SUCCESS; +} + +LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) +{ + const char szReaderName[] = "BonCasLink Proxy Card Reader\0"; + + if(pcchReaders){ + if((*pcchReaders == SCARD_AUTOALLOCATE) && mszReaders){ + *((LPCSTR *)mszReaders) = szReaderName; + return SCARD_S_SUCCESS; + } + else{ + *pcchReaders = sizeof(szReaderName); + } + } + + if(mszReaders) memcpy(mszReaders, szReaderName, sizeof(szReaderName)); + + return SCARD_S_SUCCESS; +} + +LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) +{ + // サーバにリクエスト送受信 + CCasProxy *pCasProxy = reinterpret_cast(hCard); + if(!pCasProxy)return SCARD_E_READER_UNAVAILABLE; + + DWORD dwRecvLen = pCasProxy->TransmitCommand(pbSendBuffer, cbSendLength, pbRecvBuffer); + if(pcbRecvLength)*pcbRecvLength = dwRecvLen; + + return (dwRecvLen)? SCARD_S_SUCCESS : SCARD_E_TIMEOUT; +} + +LONG SCardReleaseContext(SCARDCONTEXT hContext) { - return SCARD_S_SUCCESS; -} - -LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) -{ - return SCARD_S_SUCCESS; -} - -LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) -{ - const char szReaderName[] = "BonCasLink Proxy Card Reader\0"; - - if(pcchReaders){ - if((*pcchReaders == SCARD_AUTOALLOCATE) && mszReaders){ - *((LPCSTR *)mszReaders) = szReaderName; - return SCARD_S_SUCCESS; - } - else{ - *pcchReaders = sizeof(szReaderName); - } - } - - if(mszReaders) memcpy(mszReaders, szReaderName, sizeof(szReaderName)); - - return SCARD_S_SUCCESS; -} - -LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) -{ - // ƒT[ƒo‚ɃŠƒNƒGƒXƒg‘—ŽóM - CCasProxy *pCasProxy = reinterpret_cast(hCard); - if(!pCasProxy)return SCARD_E_READER_UNAVAILABLE; - - DWORD dwRecvLen = pCasProxy->TransmitCommand(pbSendBuffer, cbSendLength, pbRecvBuffer); - if(pcbRecvLength)*pcbRecvLength = dwRecvLen; - - return (dwRecvLen)? SCARD_S_SUCCESS : SCARD_E_TIMEOUT; -} - -LONG SCardReleaseContext(SCARDCONTEXT hContext) -{ - return SCARD_S_SUCCESS; -} + return SCARD_S_SUCCESS; +} diff --git a/b25-remote/b25-server.cpp b/b25-remote/b25-server.cpp index 674af68..1abd15a 100755 --- a/b25-remote/b25-server.cpp +++ b/b25-remote/b25-server.cpp @@ -5,9 +5,9 @@ CCasServer m_CasServer(NULL); int m_dwServerPort = 6900UL; int main() { - if(!m_CasServer.OpenServer(m_dwServerPort)){ - printf("サーバの起動に失敗しました。\nTCPポートまたはカードリーダをオープンできません。\n"); - return TRUE; + if(!m_CasServer.OpenServer(m_dwServerPort)){ + printf("サーバの起動に失敗しました。\nTCPポートまたはカードリーダをオープンできません。\n"); + return TRUE; } getchar(); }