コード例 #1
0
/*
 * Initializes the PDU Router.
 */
void PduR_Init (const PduR_PBConfigType* ConfigPtr) {

	//Enter(0);

	// Make sure the PDU Router is uninitialized.
	// Otherwise raise an error.
	if (PduRState != PDUR_UNINIT) {
		// Raise error and return.
		PDUR_DET_REPORTERROR(MODULE_ID_PDUR, PDUR_INSTANCE_ID, 0x00, PDUR_E_INVALID_REQUEST);
	}

	else if (ConfigPtr == NULL) {
		PDUR_DET_REPORTERROR(MODULE_ID_PDUR, PDUR_INSTANCE_ID, 0x00, PDUR_E_CONFIG_PTR_INVALID);
	} else {
		PduRConfig = ConfigPtr;

		// Start initialization!
		DEBUG_PRINT0(DEBUG_LOW,"--Initialization of PDU router--\n");

		//uint8 failed = 0;

		// Initialize buffers.

		/*if (failed) {
			// TODO Report PDUR_E_INIT_FAILED to Dem.
			PduRState = PDUR_REDUCED;
			DEBUG_PRINT0(DEBUG_LOW,"--Initialization of PDU router failed--\n");
		}*/

		// The initialization succeeded!
			PduRState = PDUR_ONLINE;
			DEBUG_PRINT0(DEBUG_LOW,"--Initialization of PDU router completed --\n");
	}

}
コード例 #2
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/*****************************************************************************
 * DriverEntry()
 *
 *   この関数のは System がこのドライバをロードするときに呼ばれ、ドライバを
 *   NDIS と関連付け、エントリポイントを登録する。
 * 
 * 引数:
 *     DriverObject :  ドライバーオブジェクトのポインタ
 *     RegistryPath :  ドライバーのレジストリのパス 関連付け
 *  
 * 返り値:
 * 
 *     NDIS_STATUS 
 * 
 ********************************************************************************/
NDIS_STATUS
DriverEntry(
    IN PVOID DriverObject,
    IN PVOID RegistryPath)
{
    NDIS_MINIPORT_CHARACTERISTICS  MiniportCharacteristics;
    NDIS_STATUS                    Status;

    DEBUG_PRINT0(3, "DriverEntry called\n");        

    NdisZeroMemory(&MiniportCharacteristics, sizeof(NDIS_MINIPORT_CHARACTERISTICS));

    /*
     * ミニポートドライバを NDIS に関連付けし、NdisWrapperHandle を得る。
     */
    NdisMInitializeWrapper(
        &NdisWrapperHandle, // OUT PNDIS_HANDLE  
        DriverObject,       // IN ドライバーオブジェクト
        RegistryPath,       // IN レジストリパス
        NULL                // IN 必ず NULL
        );

    if(NdisWrapperHandle == NULL){
        DEBUG_PRINT0(1, "NdisInitializeWrapper failed\n");
        return(STATUS_INVALID_HANDLE);
    }

    MiniportCharacteristics.MajorNdisVersion         = STE_NDIS_MAJOR_VERSION; // Major Version 
    MiniportCharacteristics.MinorNdisVersion         = STE_NDIS_MINOR_VERSION; // Minor Version 
    MiniportCharacteristics.CheckForHangHandler      = SteMiniportCheckForHang;     
    MiniportCharacteristics.HaltHandler              = SteMiniportHalt;             
    MiniportCharacteristics.InitializeHandler        = SteMiniportInitialize;       
    MiniportCharacteristics.QueryInformationHandler  = SteMiniportQueryInformation; 
    MiniportCharacteristics.ResetHandler             = SteMiniportReset ;            
    MiniportCharacteristics.SetInformationHandler    = SteMiniportSetInformation;   
    MiniportCharacteristics.ReturnPacketHandler      = SteMiniportReturnPacket;    
    MiniportCharacteristics.SendPacketsHandler       = SteMiniportSendPackets; 

    Status = NdisMRegisterMiniport(     
        NdisWrapperHandle,                    // IN NDIS_HANDLE                     
        &MiniportCharacteristics,             // IN PNDIS_MINIPORT_CHARACTERISTICS  
        sizeof(NDIS_MINIPORT_CHARACTERISTICS) // IN UINT                            
        );

    if( Status != NDIS_STATUS_SUCCESS){
        DEBUG_PRINT1(1, "NdisMRegisterMiniport failed(Status = 0x%x)\n", Status);
        NdisTerminateWrapper(
            NdisWrapperHandle, // IN NDIS_HANDLE  
            NULL               
            );        
        return(Status);
    }

    // グローバルロックを初期化
    NdisAllocateSpinLock(&SteGlobalSpinLock);

    NdisMRegisterUnloadHandler(NdisWrapperHandle, SteMiniportUnload);    
    
    return(NDIS_STATUS_SUCCESS);
}
コード例 #3
0
//Peer_id 为返回对方peer_id;
bool parse_handshake_info(const t_byte* pbuf, Sha1Hash &info_hash, PeerID &peer_id, t_byte ext_info[8])
{
		assert(pbuf != 0);
		
		if(pbuf[0] != PROTOCOL_LENGTH)
		{
				
				DEBUG_PRINT0("invalid protocol length\n");
				return false;
		}
		
		//DEBUG_PRINT1("%s\n", (const char*)&pbuf[1]);
		if(memcmp(&pbuf[1], PROTOCOL_STRING, PROTOCOL_LENGTH) == 0)
		{
				//DEBUG_PRINT0("invalid protocol string\n");
				memcpy(ext_info, &pbuf[20], 8); 
				info_hash.Reset(&pbuf[28]);
				peer_id.Reset(&pbuf[48]);
				return true;
		}else
		{
				DEBUG_PRINT0("invalid protocol string\n");
				return false;
		}
		
		
}
コード例 #4
0
void OutConnValidator::check_connection_handshake()
{
		assert(m_buf.Size() == 68);
		
		PeerID remote_peer_id;
		Sha1Hash info_hash;
		t_byte ext_info[8];
		bool res = parse_handshake_info(m_buf.Data(), info_hash, remote_peer_id, ext_info);

		if(!res)
		{
				DEBUG_PRINT0("parse_handshae_info failed\n");
				goto FAILED;
		}
		if(info_hash != m_infohash)
		{
				DEBUG_PRINT0("response infohash invalid\n");
				goto FAILED;
		}
		
		if(remote_peer_id == m_peer_id)
		{
				DEBUG_PRINT0("OutConnValidator::response peer id equal to local\n");
				goto FAILED;
		}
		
		MsgSpace::PostMessageEx(m_task_id, new NetConnEstablished(m_stream_sock.Duplicate(), LOCAL, remote_peer_id, m_infohash, m_peer_entry, ext_info));
		return;

FAILED:
		MsgSpace::PostMessageEx(m_task_id, new NetConnectPeerFailed(m_peer_entry));
		

}
コード例 #5
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/***************************************************************************
 * SteMiniportSendPackets()
 *
 *    NDIS Miniport エントリポイント
 *    このドライバにバインドしているプロトコルが、パケットを送信する際に
 *    NDIS によって呼ばれる。
 *
 * 引数:
 *
 *    MiniportAdapterContext :   アダプタコンテキストへのポインタ
 *    PacketArray            :   送信するパケット配列
 *    NumberOfPackets        :   上記の配列の長さ
 *
 * 返り値:
 *
 *    無し
 *    
 *************************************************************************/
VOID 
SteMiniportSendPackets(
    IN NDIS_HANDLE       MiniportAdapterContext,
    IN PPNDIS_PACKET     PacketArray,
    IN UINT              NumberOfPackets
    )
{
    UINT            i;
    NDIS_STATUS     Status;
    STE_ADAPTER    *Adapter;
    BOOLEAN         IsStedRegistered = TRUE;

    DEBUG_PRINT0(3, "SteMiniportSendPackets called\n");            

    Adapter = (STE_ADAPTER *) MiniportAdapterContext;

    // 仮想 NIC デーモンからのイベントオブジェクトが登録されているか
    // TODO: Adapter 毎の Lock を作成し、EventObject の参照時に
    // ロックを取得すべき
    if( Adapter->EventObject == NULL ) {
        DEBUG_PRINT0(2, "SteMiniportSendPackets: sted is not registerd yet\n");
        IsStedRegistered = FALSE;
    }        

    for( i = 0 ; i < NumberOfPackets ; i++){

        if(DebugLevel >= 3)
            StePrintPacket(PacketArray[i]);
        
        if(IsStedRegistered){
            Status = StePutQueue(&Adapter->SendQueue, PacketArray[i]);
        } else {
            Status = NDIS_STATUS_RESOURCES;
        }
        
        if(Status != NDIS_STATUS_SUCCESS){            
            // 送信キューが一杯、もしくは仮想 NIC デーモンが未登録のようだ。
            NdisMSendComplete(
                Adapter->MiniportAdapterHandle,  //IN NDIS_HANDLE   
                PacketArray[i],                  //IN PNDIS_PACKET  
                Status                           //IN NDIS_STATUS
                // NDIS_STATUS_RESOURCES を返すことになる。
                );
            Adapter->Oerrors++;
            continue;
        }
        
        Adapter->Opackets++;        

        /*
         * 仮想 NIC デーモンにイベント通知
         */
        KeSetEvent(Adapter->EventObject, 0, FALSE);
        DEBUG_PRINT0(3, "SteMiniportSendPackets: Notified to Daemon\n");
    }
    return;
}
コード例 #6
0
void OutConnValidator::OnInput()
{
		m_ts.Update();
		
		assert(m_buf.Size() < 68);
		t_byte buf[68];
		size_t read_n = 68 - m_buf.Size();
		assert(read_n <= 68);

		int rn = m_stream_sock.Recv(buf, read_n);
		assert(rn <= 68);

		if(rn > 0)
		{
				m_buf.Insert(buf, rn);
				assert(m_buf.Size() <= 68);

				if(m_buf.Size() == 68)
				{
						check_connection_handshake();
						GetSelector()->RemoveHandler(this);
				}
		}else if(rn == -1 && NetGetLastError() == EWOULDBLOCK)
		{
				//等待下次
		}else
		{
				DEBUG_PRINT0("OutConnValidator::OnInput connection abort\n");
				//网络连接断开
				MsgSpace::PostMessageEx(m_task_id, new NetConnectPeerFailed(m_peer_entry));
				GetSelector()->RemoveHandler(this);
		}
}
コード例 #7
0
void OutConnValidator::OnOutput()
{
		m_ts.Update();
		
		assert(m_buf.Size() > 0);
		int wn = m_stream_sock.Send(m_buf.Data(),m_buf.Size());

		if(wn > 0)
		{
				m_buf.Erase(wn);
				if(m_buf.Size() == 0)
				{
						Mask(NetSpace::INPUT_MASK|NetSpace::TIMER_MASK);
				}
		}else if(wn == -1 && NetGetLastError() == EWOULDBLOCK)
		{
				//等待下一次可写
		}else
		{
				//失败
				DEBUG_PRINT0("OutConnValidator::OnOutput() failed\n");
				MsgSpace::PostMessageEx(m_task_id, new NetConnectPeerFailed(m_peer_entry));
				GetSelector()->RemoveHandler(this);
		}

}
コード例 #8
0
bool PieceManager::GetRequest(std::list<SliceInfo> &slice_list, t_uint32 want_num, const BitField &remote_own_pieces)
{
    assert(want_num > 0);
    slice_list.clear();
    DownloadingPiece* pdown = get_best_downloading(remote_own_pieces);
    if(pdown == 0)
    {
        DEBUG_PRINT0("get_best_downloading failed\n");
        return false;
    } else
    {
        for(size_t i = 0; i < want_num; ++i)
        {
            SliceInfo si;
            if(!pdown->GetRequest(si, IsEndGame()))
            {
                DEBUG_PRINT1("pdown->GetRequest(si) failed slist.size() == %d\n", slice_list.size());
                break;
            } else
            {
                DEBUG_PRINT1("slice_list.size() == %d\n", slice_list.size());
                slice_list.push_back(si);
            }
        }
        return (slice_list.size() > 0);
    }
}
コード例 #9
0
bool PieceManager::SliceCompleted(const SliceInfo &slice_info)
{
    StartedPiecesMap::iterator it = m_started_pieces.find(slice_info.piece_idx);

    if(it == m_started_pieces.end()) return false;

    DownloadingPiece *pdown = it->second;
    if(!pdown->RequestCompleted(slice_info)) return false;

    if(pdown->IsCompleted())
    {
        if(CheckPiece(slice_info.piece_idx))
        {
            t_uint32 pidx = slice_info.piece_idx;
            assert(m_pieces_info[pidx].state == P_DOWNLOADING);
            m_pieces_info[pidx].state = P_DONE;

            t_uint32 pos = m_pos_in_interests[pidx];

            assert(pos != NONE_POS);
            m_pos_in_interests[pidx] = NONE_POS;
            std::vector<t_uint32> &piece_list = m_interests[m_pieces_info[pidx].have];
            assert(!piece_list.empty());

            if(pos == piece_list.size() - 1)
            {
                piece_list.erase(piece_list.end() - 1);
            } else
            {
                piece_list[pos] = piece_list[piece_list.size() - 1];
                m_pos_in_interests[piece_list[pos]] = pos;
                piece_list.erase(piece_list.end() - 1);
            }
            m_bitfield.Set(pidx);

            //确认此片写入磁盘中(因为此片也许会在cache中)
            m_storage.FlushPiece(pidx);

            if(!m_is_endgame && need_enter_endgame())
            {
                m_is_endgame = true;
                DEBUG_PRINT0("ENTER END GAME MODE!!!!!!!!!!!!!!!\n");
            }
        } else
        {
            DEBUG_PRINT1("Piece index == %d hash check failed\n", slice_info.piece_idx);
            ::MessageBox(0, TEXT("Piece index == hash check failed\n"), 0,0);
            t_uint32 pidx = slice_info.piece_idx;
            assert(m_pieces_info[pidx].state == P_DOWNLOADING);
            m_pieces_info[pidx].state = P_FREE;
        }

        m_started_pieces.erase(it);
        delete pdown;

    }
    return true;
}
コード例 #10
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/*******************************************************************************
 * SteMiniportCheckForHang()
 *
 *     NDIS Miniport エントリポイント
 *     NIC の状態を報告するためによばれ、またデバイスドライバの反応の有無を
 *     モニターするために呼ばれる。
 *     
 * 引数:
 * 
 *     MiniportAdapterContext :  アダプタのポインタ
 * 
 * 返り値:
 * 
 *     TRUE    NDIS がドライバの MiniportReset を呼び出した
 *     FALSE   正常
 * 
 * Note: 
 *     CheckForHang ハンドラはタイマー DPC のコンテキストで呼び出されます。
 *     この利点は、spinlock を確保/解放するときに得られます。
 * 
 ******************************************************************************/
BOOLEAN
SteMiniportCheckForHang(
    IN NDIS_HANDLE MiniportAdapterContext
    )
{
    // あまりに冗長なので、必要なデバッグレベルを上げる
    DEBUG_PRINT0(4, "SteMiniportCheckForHang called\n");
    
    return(FALSE);
}
コード例 #11
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/***************************************************************************
 * SteMiniportUnload()
 *
 *     NDIS Miniport エントリポイント
 *     アンドロードハンドラは DriverEntry の中で獲得されたリソースを解放
 *     するために、ドライバのアンロード中に呼ばれる。
 *     このハンドラは NdisMRegisterUnloadHandler を通して登録される。
 *
 *     ** 注意**
 *     MiniportUnload() は MiniportHalt() とは違う!!
 *     MiniportUload() はより広域のスコープを持つのに対し、MiniportHalt は
 *     特定の miniport ドライバインスタンスに限定される。
 * 
 * 引数:
 * 
 *     DriverObject  : 使ってない
 * 
 * 返り値:
 * 
 *     None
 *
 *************************************************************************/
VOID 
SteMiniportUnload(
    IN  PDRIVER_OBJECT      DriverObject
    )
{
    // DriverEntry() でリソースを確保していないので
    // 何もしなくてよいものか?
    DEBUG_PRINT0(3, "SteMiniportUnload called\n");            

    return;
}
コード例 #12
0
void InConnValidator::OnTimer()
{
		if(m_ts.ElapsedMillisecond() >= VALIDATOR_TIMEOUT)
		{
				//MsgSpace::PostMessageEx(m_task_id, new NetConnectPeerFailed(m_peer_entry));
				DEBUG_PRINT0("accepted peer connection timeout\n");
				GetSelector()->RemoveHandler(this);
		}


}
コード例 #13
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/***************************************************************************
 * SteMiniportSetInformation()
 *
 *  NDIS エントリポイント
 *  OID の値を問い合わせるために NDIS によって呼ばれる。
 * 
 * 引数:
 * 
 *     MiniportAdapterContext  :    Adapter 構造体のポインタ
 *     Oid                     :    この問い合わせの OID
 *     InformationBuffer       :    情報のためのバッファー
 *     InformationBufferLength :    バッファのサイズ
 *     BytesRead               :    いくつの情報が読まれたか
 *     BytesNeeded             :    バッファが少ない場合に必要なサイズを指示
 * 
 * 返り値:
 * 
 *     正常時 : NDIS_STATUS_SUCCESS
 * 
 *******************************************************************************/
NDIS_STATUS
SteMiniportSetInformation(
    IN NDIS_HANDLE  MiniportAdapterContext,
    IN NDIS_OID     Oid,
    IN PVOID        InformationBuffer,
    IN ULONG        InformationBufferLength,
    OUT PULONG      BytesRead,
    OUT PULONG      BytesNeeded)
{
    NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
    STE_ADAPTER    *Adapter;
    ULONG           NewFilter;

    DEBUG_PRINT0(3, "SteMiniportSetInformation called\n");        

    Adapter   =    (STE_ADAPTER *)MiniportAdapterContext;

    DEBUG_PRINT1(3, "SteMiniportSetInformation: Oid = 0x%x\n", Oid);
    
    // 必須 OID のセット要求だけを実装
    // TODO:
    // 今のところ、パケットフィルター以外は実際にはセットしていないので、セットできるようにする。
    //
    switch(Oid) {
        // 一般的な特性         
        case OID_GEN_CURRENT_PACKET_FILTER:
            if(InformationBufferLength != sizeof(ULONG)){
                *BytesNeeded = sizeof(ULONG);
                *BytesRead = 0;
                Status = NDIS_STATUS_INVALID_LENGTH;
                break;
            }
            NewFilter = *(ULONG *)InformationBuffer;
            Adapter->PacketFilter = NewFilter;
            *BytesRead = InformationBufferLength;
            DEBUG_PRINT1(3,"SteMiniportSetInformation: New filter = 0x%x (See ntddndis.h)\n", NewFilter);
            break;
        case OID_GEN_CURRENT_LOOKAHEAD:
            *BytesRead = InformationBufferLength;
            break;
        case OID_GEN_PROTOCOL_OPTIONS:
            *BytesRead = InformationBufferLength;
            break;        
        // Ethernet の特性
        case OID_802_3_MULTICAST_LIST:
            *BytesRead = InformationBufferLength;
            break;            
        default:
            Status = NDIS_STATUS_INVALID_OID;            
            break;
    }
    
    return(Status);
}
コード例 #14
0
bool InConnValidator::check_connection_handshake()
{
		assert(m_buf.Size() == 68);

		PeerID remote_peer_id;
		
		if(parse_handshake_info(m_buf.Data(), m_infohash, remote_peer_id, m_ext_info))
		{
				DownloaderInfo dl_info;
				if(m_res_manager.GetDownloaderRecorder().GetRecord(m_infohash, dl_info))
				{
						if(dl_info.peer_id == remote_peer_id)
						{
								DEBUG_PRINT0("InConnValidator::remote peer id equal to local\n");
								NetSpace::InetAddress addr;
								m_stream_sock.GetLocalAddr(addr);//因为这个很可能是自己,反正无论如何也要band
								m_res_manager.GetIPFilter().BandAddress(addr.Str(), addr.Port());
								DEBUG_PRINT2("InConnValidator::check_connection_handshake : band peer entry == %s:%d\n", addr.Str().c_str(), addr.Port());
								return false;
						}

						m_task_id = dl_info.task_id;
						m_infohash = dl_info.info_hash;
						m_peer_id = remote_peer_id;
						
						m_buf.Clear();
						m_buf.Insert(&build_hand_shake(m_infohash, dl_info.peer_id)[0], 68);
						assert(m_buf.Size() == 68);
						return true;
				}else
				{
						DEBUG_PRINT0("unknow infohash\n");
						return false;
				}

		}else
		{
				DEBUG_PRINT0("parse_handshake_info failed\n");
				return false;
		}
}
コード例 #15
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/****************************************************************************
 * SteMiniportShutdown()
 *
 *   NDIS エントリポイント
 *   システムのシャットダウンや、予期せぬシステムエラー時に、NIC を初期状態
 *   に戻すために呼ばれる。ここではメモリリソースを解放したり、パケットの転
 *   送完了を待ったりはしない
 *
 * 引数:
 *
 *    ShutdownContext : STE_ADAPTER 構造体のポインタ
 *
 * 戻り値:
 *
 *    無し
 *
***************************************************************************/
VOID
SteMiniportShutdown(
    IN PVOID  ShutdownContext
    )
{
    STE_ADAPTER     *Adapter;

    DEBUG_PRINT0(3, "SteMiniportShutdown called\n");        

    Adapter = (STE_ADAPTER *)ShutdownContext;

    return;
}
コード例 #16
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/******************************************************************************
 * SteMiniportReset()
 *
 *    NDIS Miniport エントリポイント
 *    以下の条件のとき NIC がハングしていると判断しドライバーのソフトステート
 *    をリセットするために呼ばれる。
 *
 *     1) SteMiniportCheckForHang() が TRUE を返してきた
 *     2) 未処理の送信パケットを検出した(シリアライズドドライバのみ)
 *     3) 一定時間内に完了することができなかった未処理の要求があった
 *
 *   この関数の中では以下を行う
 *   
 *     1) キューイングされている送信パケットの処理をやめ、NDIS_STATUS_REQUEST_ABORTED を返す。
 *     2) 上位に通知した全てのパケットがリターンしてきたか確認する。
 *     3) 上記2つに問題がありリセット処理をただちに完了できない場合、ResetTimer をセットし、
 *        NDIS_STATUS_PENDING を返す。

 * 
 * 引数:
 * 
 *    AddressingReset        : マルチキャストや、MAC アドレス、lookahead サイズ
 *                             に変更があった場合にはここを TRUE にしなければならない。
 *                             
 *    MiniportAdapterContext : STE_ADAPTER 構造体のポインタ                  
 * 
 * 
 *   返り値:
 * 
 *     NDIS_STATUS
 * 
 **************************************************************************/
NDIS_STATUS
SteMiniportReset(
    OUT PBOOLEAN     AddressingReset,
    IN  NDIS_HANDLE  MiniportAdapterContext
    )
{
    NDIS_STATUS        Status;
    STE_ADAPTER       *Adapter;
    NDIS_PACKET       *Packet = NULL;

    DEBUG_PRINT0(3, "SteMiniportReset called\n");

    Adapter = (STE_ADAPTER *)MiniportAdapterContext;

    // MAC アドレス、マルチキャストアドレスの変更はない!?ときめつけて FALSE を返す
    *AddressingReset = FALSE;    

    Status = NDIS_STATUS_REQUEST_ABORTED;

    // 送信キューに入っているパケットを処理する
    while (SteGetQueue(&Adapter->SendQueue, &Packet) == NDIS_STATUS_SUCCESS) {
        NdisMSendComplete(
            Adapter->MiniportAdapterHandle,  //IN NDIS_HANDLE   
            Packet,                          //IN PNDIS_PACKET  
            Status                           //IN NDIS_STATUS   
            );
    }

    // 受信キューに入っているパケットを処理する
    while (SteGetQueue(&Adapter->RecvQueue, &Packet) == NDIS_STATUS_SUCCESS) {
        SteFreeRecvPacket(Adapter, Packet);
    }
    // これが終われば、全ての受信パケットがフリーされているはず。
    // 後は上位プロトコルに通知済みでまだ戻ってきていないパケットがあるかどうかを
    // 確認する。

    if (Adapter->RecvIndicatedPackets > 0) {
        // まだ戻ってきてないパケットがあるようだ。
        // リセットタイマーをセットして、後ほど SteResetTimerFunc() から
        // NdisMResetComplete() を呼んでリセットを完了することにする。
        NdisSetTimer(&Adapter->ResetTimer, 300);
        Status = NDIS_STATUS_PENDING;
    } else {
        // リセット操作完了!
        Status = NDIS_STATUS_SUCCESS;
    }

    return(Status);
}
コード例 #17
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/**************************************************************************
 * SteMiniportReturnPacket()   
 *
 *    NDIS Miniport エントリポイント
 *    このドライバが上位プロトコルに通知したパケットが、プロトコルによって
 *    処理が終了した場合に NDIS によって呼ばれる。
 *
 * 引数:
 *
 *    MiniportAdapterContext :  ADAPTER 構造体のポインタ
 *    Packet                 :  リターンされてきたパケット
 *
 * 返り値:
 *
 *    無し
 *
 **************************************************************************/
VOID 
SteMiniportReturnPacket(
    IN NDIS_HANDLE   MiniportAdapterContext,
    IN PNDIS_PACKET  Packet)
{
    STE_ADAPTER         *Adapter;

    Adapter = (STE_ADAPTER *)MiniportAdapterContext;

    DEBUG_PRINT0(3, "SteMiniportReturnPacket called\n");    

    SteFreeRecvPacket(
        Adapter,  //IN STE_ADAPTER
        Packet    //IN NDIS_PACKET
        );

    NdisInterlockedDecrement(
        (PLONG)&Adapter->RecvIndicatedPackets  //IN PLONG  
    );    
    
    return;
}
コード例 #18
0
void InConnValidator::OnInput()
{
		m_ts.Update();
		t_byte buf[68];

		int read_len = 68 - m_buf.Size();
		
		assert(read_len <= 68);

		int rn = m_stream_sock.Recv(buf, read_len);

		if(rn > 0)
		{
				m_buf.Insert(buf, rn);
				assert(m_buf.Size() <= 68);

				if(m_buf.Size() == 68)
				{
						if(!check_connection_handshake())
						{
								//DEBUG_PRINT0("check_connection_handshake failed\n");
								GetSelector()->RemoveHandler(this);
								return;
						}else
						{
								assert(m_buf.Size() == 68);
								Mask(NetSpace::OUTPUT_MASK|NetSpace::TIMER_MASK);
						}
				}
		}else if(rn == -1 && NetGetLastError() == EWOULDBLOCK)
		{
				//等待下次;
		}else
		{
				DEBUG_PRINT0("accepted peer connection abort\n");
				GetSelector()->RemoveHandler(this);
		}
}
コード例 #19
0
void InConnValidator::OnOutput()
{
		m_ts.Update();
		
		int wn = m_stream_sock.Send(m_buf.Data(), m_buf.Size());
		
		if(wn > 0)
		{
				m_buf.Erase(wn);
				if(m_buf.IsEmpty())
				{
						MsgSpace::PostMessageEx(m_task_id, new NetConnEstablished(m_stream_sock.Duplicate(), REMOTE, m_peer_id, m_infohash, m_peer_entry, m_ext_info));
						GetSelector()->RemoveHandler(this);
				}
		}else if(wn == -1 && NetGetLastError() == EWOULDBLOCK)
		{
				//等待下次;
		}else
		{
				DEBUG_PRINT0("accepted peer connection abort\n");
				GetSelector()->RemoveHandler(this);
		}
}
コード例 #20
0
void Com_Init(const Com_ConfigType *config ) {
	uint8 failure = 0;
	uint32 firstTimeout;
	uint8 endiannessByte;
	uint16 i;
	uint16 j;
    //ComIPdu_type *IPdu;
	//Com_Arc_IPdu_type *Arc_IPdu;
	const ComSignal_type *Signal;
	const ComGroupSignal_type *GroupSignal;
	
	DEBUG_PRINT0(DEBUG_LOW, "--Initialization of COM--\n");

	ComConfig = config;

	//lint --e(928)	PC-Lint exception Misra 11.4, Must be like this. /tojo
	endiannessByte = *(const uint8 *)&endianness_test;
	if      ( endiannessByte == 0xef ) { Com_SystemEndianness = COM_LITTLE_ENDIAN; }
	else if ( endiannessByte == 0xde ) { Com_SystemEndianness = COM_BIG_ENDIAN; }
	else {
		// No other endianness supported
		//lint --e(506)	PC-Lint exception Misra 13.7, 14.1, Allow boolean to always be false.
		AR_ASSERT(0);
	}

	// Initialize each IPdu
#if 0
	//F*****g bad code as always need a dummy ComIPdu config with Com_Arc_EOL equal to TRUE.
	for (i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
#else /*So I changed it to ...*/
    for(i = 0;i < COM_N_IPDUS;i++){
#endif
		const ComIPdu_type *IPdu = GET_IPdu(i);
		Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(i);
		Arc_IPdu->Com_Arc_DynSignalLength = 0;

		if (i >= COM_N_IPDUS) {
			DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_TOO_MANY_IPDU);
			failure = 1;
			break;
		}

		// If this is a TX and cyclic IPdu, configure the first deadline.
		if ( (IPdu->ComIPduDirection == SEND) &&
             ( (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == PERIODIC) || (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == MIXED) )) {
			//IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeTimeOffsetFactor;
			Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeTimeOffsetFactor;
		}


		// Reset firstTimeout.
		firstTimeout = 0xffffffffu;

		// Initialize the memory with the default value.
		if (IPdu->ComIPduDirection == SEND) {
			memset((void *)IPdu->ComIPduDataPtr, IPdu->ComTxIPdu.ComTxIPduUnusedAreasDefault, IPdu->ComIPduSize);
		}

		// For each signal in this PDU.
		//Arc_IPdu->NComIPduSignalRef = 0;
		for (j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL) ; j++) {
			Com_Arc_Signal_type * Arc_Signal;
			Signal = IPdu->ComIPduSignalRef[j];
			Arc_Signal = GET_ArcSignal(Signal->ComHandleId);

			// Configure signal deadline monitoring if used.
			if (Signal->ComTimeoutFactor > 0) {

				if (Signal->ComSignalArcUseUpdateBit) {
					// This signal uses an update bit, and hence has its own deadline monitoring.
					Arc_Signal->Com_Arc_DeadlineCounter = Signal->ComFirstTimeoutFactor; // Configure the deadline counter

				} else {
					// This signal does not use an update bit, and should therefore use per I-PDU deadline monitoring.
					if (firstTimeout > Signal->ComFirstTimeoutFactor) {
						firstTimeout = Signal->ComFirstTimeoutFactor;
					}
				}
			}

			// Clear update bits
			if (Signal->ComSignalArcUseUpdateBit) {
				CLEARBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
			}

			// If this signal is a signal group
			if (Signal->Com_Arc_IsSignalGroup) {
			    uint8 h;
				// For each group signal of this signal group.
				for(h = 0; Signal->ComGroupSignal[h] != NULL; h++) {
					Com_Arc_GroupSignal_type *Arc_GroupSignal;
					GroupSignal = Signal->ComGroupSignal[h];
					Arc_GroupSignal = GET_ArcGroupSignal(GroupSignal->ComHandleId);
					// Set pointer to shadow buffer
					Arc_GroupSignal->Com_Arc_ShadowBuffer = (void *)Signal->Com_Arc_ShadowBuffer;
					// Initialize group signal data.
					Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, GroupSignal->ComHandleId, GroupSignal->ComSignalInitValue);
				}
			} else {
				// Initialize signal data.
				Com_WriteSignalDataToPdu(Signal->ComHandleId, Signal->ComSignalInitValue);
			}
		}
		if (IPdu->ComIPduDirection == RECEIVE && IPdu->ComIPduSignalProcessing == DEFERRED) {
			// Copy the initialized pdu to deferred buffer
			memcpy(IPdu->ComIPduDeferredDataPtr,IPdu->ComIPduDataPtr,IPdu->ComIPduSize);
		}
		// Configure per I-PDU based deadline monitoring.
		for (j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL); j++) {
			Com_Arc_Signal_type * Arc_Signal;
			Signal = IPdu->ComIPduSignalRef[j];
			Arc_Signal = GET_ArcSignal(Signal->ComHandleId);

			if ( (Signal->ComTimeoutFactor > 0) && (!Signal->ComSignalArcUseUpdateBit) ) {
				Arc_Signal->Com_Arc_DeadlineCounter = firstTimeout;
			}
		}
	}
	for (i = 0; i < COM_N_IPDUS; i++) {
		Com_BufferPduState[i].currentPosition = 0;
		Com_BufferPduState[i].locked = FALSE;
	}

	// An error occurred.
	if (failure) {
		DEBUG_PRINT0(DEBUG_LOW, "--Initialization of COM failed--\n");
		//DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_INVALID_FILTER_CONFIGURATION);
	} else {
		DEBUG_PRINT0(DEBUG_LOW, "--Initialization of COM completed--\n");
	}
}


void Com_DeInit( void ) {

}

void Com_IpduGroupStart(Com_PduGroupIdType IpduGroupId,boolean Initialize) {
    uint16 i;
	(void)Initialize; // Nothing to be done. This is just to avoid Lint warning.
#if 0
	for (i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
#else /*So I changed it to ...*/
    for(i = 0;i < COM_N_IPDUS;i++){
#endif
		if (ComConfig->ComIPdu[i].ComIPduGroupRef == IpduGroupId) {
			Com_Arc_Config.ComIPdu[i].Com_Arc_IpduStarted = 1;
		}
	}
}

void Com_IpduGroupStop(Com_PduGroupIdType IpduGroupId) {
    uint16 i;
#if 0
	for (i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
#else /*So I changed it to ...*/
    for(i = 0;i < COM_N_IPDUS;i++){
#endif
		if (ComConfig->ComIPdu[i].ComIPduGroupRef == IpduGroupId) {
			Com_Arc_Config.ComIPdu[i].Com_Arc_IpduStarted = 0;
		}
	}
}

/**
 *
 * @param PduId
 * @param PduInfoPtr
 * @param RetryInfoPtr not supported
 * @param TxDataCntPtr
 * @return
 */
BufReq_ReturnType Com_CopyTxData(PduIdType PduId, PduInfoType* PduInfoPtr, RetryInfoType* RetryInfoPtr, PduLengthType* TxDataCntPtr) {
	imask_t state;
	BufReq_ReturnType r = BUFREQ_OK;
	const ComIPdu_type *IPdu = GET_IPdu(PduId);
	boolean dirOk = ComConfig->ComIPdu[PduId].ComIPduDirection == SEND;
	boolean sizeOk;
	(void)RetryInfoPtr; // get rid of compiler warning

	Irq_Save(state);
	sizeOk = IPdu->ComIPduSize >= Com_BufferPduState[PduId].currentPosition + PduInfoPtr->SduLength;
	Com_BufferPduState[PduId].locked = TRUE;
	if (dirOk && sizeOk) {
		void* source = (void *)(IPdu->ComIPduDataPtr);
		memcpy((void *)PduInfoPtr->SduDataPtr,(void *)((uint8*)source + Com_BufferPduState[PduId].currentPosition), PduInfoPtr->SduLength);
		Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;
		*TxDataCntPtr = IPdu->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
	} else {
		r = BUFREQ_NOT_OK;
	}
	Irq_Restore(state);
	return r;
}
コード例 #21
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/************************************************************************
 * SteMiniportHalt()
 *
 *     NDIS Miniport エントリポイント
 *     Halt ハンドラは NDIS が PNP マネージャから IRP_MN_STOP_DEVICE、
 *     IRP_MN_SUPRISE_REMOVE、IRP_MN_REMOVE_DEVICE 要求を受け取ったと
 *     きに呼ばれる。SteMiniportInitialize で確保された全てのリソース
 *     を解放する。(特定のミニポートドライバインスタンスに限定される)
 *     
 *     o 全ての I/O リソースを free し、unmap する。
 *     o NdisMRegisterAdapterShutdownHandler によって登録されたシャッ
 *       トダウンハンドラを登録解除する。
 *     o NdisMCancelTimer を呼んでキューイングされているコールバック
 *       ルーチンをキャンセルする。
 *     o 全ての未処理の受信パケットが処理され終わるまで待つ。
 * 
 * 引数:
 *      MiniportAdapterContext	アダプタへのポインタ
 *  
 * 返り値:
 * 
 *     無し
********************************************************************/
VOID 
SteMiniportHalt(
    IN  NDIS_HANDLE    MiniportAdapterContext
    )
{
    STE_ADAPTER       *Adapter;
    BOOLEAN            bTimerCancelled;
    INT                i;

    DEBUG_PRINT0(3, "SteMiniportHalt called\n");        

    Adapter = (STE_ADAPTER *) MiniportAdapterContext;
    
    SteMiniportShutdown(
        (PVOID) Adapter   //IN PVOID
        );

    //
    // NdisMCancelTimer を呼んでキューイングされているコールバック
    // ルーチンをキャンセルする。
    //

    // ReceiveIndication タイマーをキャンセル
    NdisCancelTimer(
        &Adapter->RecvTimer,  // IN  PNDIS_TIMER
        &bTimerCancelled      // OUT PBOOLEAN  
        );
    // Reset タイマーをキャンセル    
    NdisCancelTimer(
        &Adapter->ResetTimer, // IN  PNDIS_TIMER
        &bTimerCancelled      // OUT PBOOLEAN  
        );
    if (bTimerCancelled == TRUE){
        // キャンセルされたコールバックルーチンがあったようだ。
        // 受信キューに残っている Packet はこの後の SteDeleteAdapter()
        // によって Free されるので、ここでは何もしない。
    }

    // NdisMRegisterAdapterShutdownHandler によって登録された
    // シャットダウンハンドラを登録解除する。    
    NdisMDeregisterAdapterShutdownHandler(
        Adapter->MiniportAdapterHandle // IN NDIS_HANDLE 
        );

    //
    // 仮想 NIC デーモンからの IOCT/READ/WRITE 用のデバイスの登録を解除する。
    //
    SteDeregisterDevice(Adapter);

    //
    // 処理中の受信通知済みパケットがないかどうかチェックする。
    // 1 秒おきに、STE_MAX_WAIT_FOR_RECVINDICATE(=5)回確認し、
    // RecvIndicatedPackets が 0 にならないようであれば、
    // なにか問題があったと考え無視してリソースの開放に進む。
    //
    for ( i = 0 ; i < STE_MAX_WAIT_FOR_RECVINDICATE ; i++){
        if (Adapter->RecvIndicatedPackets == 0) {
            break;
        }
        NdisMSleep(1000);
    }
    
    //
    // Adapter を削除する。このなかで、Adapter の為に確保されたリソースの
    // 開放も(Packet や、Buffer)行われる。
    //
    SteDeleteAdapter(Adapter);

    return;
}
コード例 #22
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/*************************************************************************
 * SteMiniportinitialize()
 *
 *  NDIS エントリポイント
 *   ネットワーク I/O 操作のために NIC ドライバがネットワーク I/O 操作を
 *   するために必要なリソースを確保する。
 *
 *  引数:
 *
 *         OpenErrorStatus              OUT PNDIS_STATUS 
 *         SelectedMediumIndex          OUT PUINT        
 *         MediumArray                  IN PNDIS_MEDIUM  
 *         MediumArraySize              IN UINT          
 *         MiniportAdapterHandle        IN NDIS_HANDLE   
 *         WrapperConfigurationContext  IN NDIS_HANDLE   
 *
 *  返り値:
 *    
 *     正常時: NDIS_STATUS_SUCCESS
 *
 *************************************************************************/
NDIS_STATUS 
SteMiniportInitialize(
    OUT PNDIS_STATUS OpenErrorStatus,
    OUT PUINT        SelectedMediumIndex,
    IN PNDIS_MEDIUM  MediumArray,
    IN UINT          MediumArraySize,
    IN NDIS_HANDLE   MiniportAdapterHandle,
    IN NDIS_HANDLE   WrapperConfigurationContext
    )
{
    UINT             i;
    NDIS_STATUS     Status  = NDIS_STATUS_SUCCESS;
    STE_ADAPTER    *Adapter = NULL;
    BOOLEAN          MediaFound = FALSE;

    DEBUG_PRINT0(3, "SteMiniportInitialize called\n");    

    *SelectedMediumIndex = 0;
    
    for ( i = 0 ; i < MediumArraySize ; i++){
        if (MediumArray[i] == NdisMedium802_3){
            *SelectedMediumIndex = i;
            MediaFound = TRUE;
            break;
        }
    }

    // 途中で break するためだけの Do-While 文
    do {
        if(!MediaFound){
            // 上記の for 文で見つけられなかったようだ
            DEBUG_PRINT0(1, "SteMiniportInitialize: No Media much\n");        
            Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
            break;
        }

        //
        // Adapter を確保し、初期化する
        //
        if ((Status = SteCreateAdapter(&Adapter)) != NDIS_STATUS_SUCCESS){
            DEBUG_PRINT0(1, "SteMiniportInitialize: Can't allocate memory for STE_ADAPTER\n");
            Status = NDIS_STATUS_RESOURCES;
            break;
        }

        DEBUG_PRINT1(3, "SteMiniportInitialize: Adapter = 0x%p\n", Adapter);        

        Adapter->MiniportAdapterHandle = MiniportAdapterHandle;

        //
        // Registory を読む処理。...省略。
        //    NdisOpenConfiguration();
        //    NdisReadConfiguration();
        //
        // NIC のためのハードウェアリソースのリストを得る。...省略。
        //    NdisMQueryAdapterResources()
        //

        //
        // NDIS に NIC の情報を伝える。
        // かならず NdisXxx 関数を呼び出すより前に、以下の NdisMSetAttributesEx
        // を呼び出さなければならない。
        //
        NdisMSetAttributesEx(
            MiniportAdapterHandle,       //IN NDIS_HANDLE 
            (NDIS_HANDLE) Adapter,       //IN NDIS_HANDLE 
            0,                           //IN UINT  
            NDIS_ATTRIBUTE_DESERIALIZE,  //IN ULONG  Deserialized ミニポートドライバ
            NdisInterfaceInternal        //IN NDIS_INTERFACE_TYPE 
            );

        //
        // NDIS 5.0 の場合はかならず SHUTDOWN_HANDLER を登録しなければならない。
        //
        NdisMRegisterAdapterShutdownHandler(
            MiniportAdapterHandle,                         // IN NDIS_HANDLE
            (PVOID) Adapter,                               // IN PVOID 
            (ADAPTER_SHUTDOWN_HANDLER) SteMiniportShutdown // IN ADAPTER_SHUTDOWN_HANDLER  
            );

        //
        // 仮想 NIC デーモンからの IOCT/ReadFile/WriteFile 用の
        // デバイスを作成し、Dispatch ルーチンを登録する。
        //
        SteRegisterDevice(Adapter);
    
        //
        // SteRecvTimerFunc() を呼ぶためのタイマーオブジェクトを初期化
        //

        NdisInitializeTimer(
            &Adapter->RecvTimer,     //IN OUT PNDIS_TIMER  
            SteRecvTimerFunc,        //IN PNDIS_TIMER_FUNCTION      
            (PVOID)Adapter           //IN PVOID
            );
        //
        // SteResetTimerFunc() を呼ぶためのタイマーオブジェクトを初期化
        //
        NdisInitializeTimer(
            &Adapter->ResetTimer,    //IN OUT PNDIS_TIMER  
            SteResetTimerFunc,       //IN PNDIS_TIMER_FUNCTION      
            (PVOID)Adapter           //IN PVOID
            );
        
    } while (FALSE);
    
    
    return(Status);
}
コード例 #23
0
ファイル: ste.c プロジェクト: kaizawa/vpn-ste-win
/************************************************************************
 * SteMiniportQueryInformation()
 *
 *  NDIS エントリポイント
 *  OID の値を問い合わせるために NDIS によって呼ばれる。
 * 
 * 引数:
 * 
 *     MiniportAdapterContext  :   STE_ADAPTER 構造体のポインタ
 *     Oid                     :   この問い合わせの OID
 *     InformationBuffer       :   情報のためのバッファー
 *     InformationBufferLength :   バッファのサイズ
 *     BytesWritten            :   いくつの情報が記述されたか
 *     BytesNeeded             :   バッファが少ない場合に必要なサイズを指示
 * 
 * 返り値:
 *
 *     正常時 :  NDIS_STATUS_SUCCESS
 *     
 ************************************************************************/
NDIS_STATUS
SteMiniportQueryInformation(
    IN NDIS_HANDLE  MiniportAdapterContext,
    IN NDIS_OID     Oid,
    IN PVOID        InformationBuffer,
    IN ULONG        InformationBufferLength,
    OUT PULONG      BytesWritten,
    OUT PULONG      BytesNeeded
    )
{
    NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
    STE_ADAPTER    *Adapter;
    PVOID           Information = NULL;     // 提供する情報へのポインタ
    ULONG           InformationLength = 0;  // 提供する情報の長さ
    ULONG           ulTemp;                 // 整数値の情報のための領域(マクロ内で利用)
    CHAR            VendorName[] = STE_VENDOR_NAME; // ベンダー名

    // あまりに冗長なので、必要なデバッグレベルを上げる    
    DEBUG_PRINT0(4, "SteMiniportQueryInformation called\n");    

    Adapter = (STE_ADAPTER *)MiniportAdapterContext;

    DEBUG_PRINT1(4, "SteMiniportQueryInformation: Oid = 0x%x\n", Oid);        

    switch(Oid) {    
        // 一般的な特性 (22個)
        case OID_GEN_SUPPORTED_LIST:        //サポートされる OID のリスト
            SET_INFORMATION_BY_POINTER(sizeof(STESupportedList), &STESupportedList);
            
        case OID_GEN_HARDWARE_STATUS:       // ハードウェアステータス
            SET_INFORMATION_BY_VALUE(sizeof(NDIS_HARDWARE_STATUS), NdisHardwareStatusReady);
            
        case OID_GEN_MEDIA_SUPPORTED:       // NIC がサポートできる(が必須ではない)メディアタイプ
        case OID_GEN_MEDIA_IN_USE:          // NIC が現在使っている完全なメディアタイプのリスト
            SET_INFORMATION_BY_VALUE(sizeof(NDIS_MEDIUM), NdisMedium802_3);
            
        case OID_GEN_MAXIMUM_LOOKAHEAD:     // NIC が lookahead データとして提供できる最大バイト数
        case OID_GEN_MAXIMUM_FRAME_SIZE:    // NIC がサポートする、ヘッダを抜いたネットワークパケットサイズ
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), ETHERMTU);
            
        case OID_GEN_LINK_SPEED:            //NIC がサポートする最大スピード
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), ETHERLINKSPEED);
            
        case OID_GEN_TRANSMIT_BUFFER_SPACE: // NIC 上の送信用のメモリの総量
            // TODO: これでいいのか?
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), ETHERMTU);
            
        case OID_GEN_RECEIVE_BUFFER_SPACE:  // NIC 上の受信用のメモリの総量
            // TODO: これでいいのか?
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), ETHERMTU);            
            
        case OID_GEN_TRANSMIT_BLOCK_SIZE:   // NIC がサポートする送信用のネットワークパケットサイズ
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), ETHERMAX);                        

        case OID_GEN_RECEIVE_BLOCK_SIZE:    // NIC がサポートする受信用のネットワークパケットサイズ
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), ETHERMAX);                                    

        case OID_GEN_VENDOR_ID:             // IEEE に登録してあるベンダーコード
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), 0xFFFFFF);            
            
        case OID_GEN_VENDOR_DESCRIPTION:    // NIC のベンダー名
            SET_INFORMATION_BY_POINTER(sizeof(VendorName), VendorName);
            
        case OID_GEN_VENDOR_DRIVER_VERSION: // ドライバーのバージョン
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), STE_DRIVER_VERSION);                        

        case OID_GEN_CURRENT_PACKET_FILTER: // プロトコルが NIC から受け取るパケットのタイプ
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), Adapter->PacketFilter);
            
        case OID_GEN_CURRENT_LOOKAHEAD:     // 現在の lookahead のバイト数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), ETHERMTU);
            
        case OID_GEN_DRIVER_VERSION:        // NDIS のバージョン
            SET_INFORMATION_BY_VALUE(sizeof(USHORT), STE_NDIS_VERSION);
            
        case OID_GEN_MAXIMUM_TOTAL_SIZE:    // NIC がサポートするネットワークパケットサイズ
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), ETHERMAX);
            
       // case OID_GEN_PROTOCOL_OPTIONS:      // オプションのプロトコルフラグ。Set のみ必須
                    
        case OID_GEN_MAC_OPTIONS:           // 追加の NIC のプロパティを定義したビットマスク
            SET_INFORMATION_BY_VALUE(sizeof(ULONG),
                                     NDIS_MAC_OPTION_NO_LOOPBACK |
                                     NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
                                     NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA);

        case OID_GEN_MEDIA_CONNECT_STATUS:  // NIC 上の connection 状態
            // TODO: 状態を確認し、NdisMediaStateDisconnected を返すようにする
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), NdisMediaStateConnected);
            
        case OID_GEN_MAXIMUM_SEND_PACKETS:  // 一回のリクエストで受けられるパケットの最大数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), STE_MAX_SEND_PACKETS);

        // 一般的な統計情報 (5個)
        case OID_GEN_XMIT_OK:               // 正常に送信できたフレーム数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), Adapter->Opackets);

        case OID_GEN_RCV_OK:                // 正常に受信できたフレーム数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), Adapter->Ipackets);            

        case OID_GEN_XMIT_ERROR:            // 送信できなかった(もしくはエラーになった)フレーム数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), Adapter->Oerrors);
            
        case OID_GEN_RCV_ERROR:             // 受信できなかった(もしくはエラーになった)フレーム数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), Adapter->Ierrors);
            
        case OID_GEN_RCV_NO_BUFFER:         // バッファ不足のために受信できなかったフレーム数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), Adapter->NoResources);            
            
       // Ethernet 用の特性 (4個)
        case OID_802_3_PERMANENT_ADDRESS:   // ハードウェアに書かれている MAC アドレス
        case OID_802_3_CURRENT_ADDRESS:     // NIC の現在の MAC アドレス            
            SET_INFORMATION_BY_POINTER(ETHERADDRL, Adapter->EthernetAddress);
            
        case OID_802_3_MULTICAST_LIST:     // 現在のマルチキャストパケットのアドレスリスト
            // TODO: マルチキャストリストをセットする。
            // 今のところ 0 を返す
            SET_INFORMATION_BY_VALUE(ETHERADDRL, 0);            
            
        case OID_802_3_MAXIMUM_LIST_SIZE:  // NIC ドライバが管理できる最大のマルチキャストアドレスの数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), STE_MAX_MCAST_LIST);
            
        // Ethernet 用統計情報  (3個)
        case OID_802_3_RCV_ERROR_ALIGNMENT:   // アライメントエラーの受信フレーム数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), Adapter->AlignErrors);

        case OID_802_3_XMIT_ONE_COLLISION:    // コリジョンが 1 回発生した送信フレーム数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), Adapter->OneCollisions);

        case OID_802_3_XMIT_MORE_COLLISIONS:  // コリジョンが 1 回以上発生した送信フレーム数
            SET_INFORMATION_BY_VALUE(sizeof(ULONG), Adapter->Collisions);            

        default:
            Status = NDIS_STATUS_NOT_SUPPORTED;
            break;                        
    }

    if(Information != NULL) {
        NdisMoveMemory(InformationBuffer, Information, InformationLength);        
        *BytesWritten = InformationLength;
    } else if(InformationLength > 0) {
        // バッファが小さい場合は、必要なサイズを通知する。
        *BytesNeeded = InformationLength;
        Status = NDIS_STATUS_BUFFER_TOO_SHORT;
    }
    return(Status);    
}