⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 obexirdatransport.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "common.h"
#include "ObexIRDATransport.h"
#include "IRDATransportSocket.h"
#include "CObex.h"
#include "PropertyBag.h"
#include "PropertyBagEnum.h"

#include "ObexStrings.h"

/*----------globals---------------*/
LPSOCKET CObexIRDATransport::pSocket = 0;

CObexIRDATransport::CObexIRDATransport() : _refCount(1), dwTimeOfLastEnum(0), fIsAborting(FALSE)
{
    DEBUGMSG(OBEX_IRDATRANSPORT_ZONE,(L"CObexIRDATransport::CObexIRDATransport()\n"));
    
    //initilize the socket libs
    WSADATA wsd;
    WSAStartup (MAKEWORD(2,2), &wsd);   
}

CObexIRDATransport::~CObexIRDATransport()
{
    DEBUGMSG(OBEX_IRDATRANSPORT_ZONE,(L"CObexIRDATransport::~CObexIRDATransport()\n"));
    
    //clean up winsock
    WSACleanup();
}

HRESULT STDMETHODCALLTYPE 
CObexIRDATransport::Init(void)
{
    DEBUGMSG(OBEX_IRDATRANSPORT_ZONE,(L"CObexIRDATransport::Init()\n"));
    return S_OK;
}


HRESULT STDMETHODCALLTYPE 
CObexIRDATransport::Shutdown(void)
{
    return S_OK;
}

HRESULT STDMETHODCALLTYPE
//singleton that holds a socket object 
CObexIRDATransport::CreateSocket(LPPROPERTYBAG2 pPropertyBag,
                                 LPSOCKET  *ppSocket)
{
    DEBUGMSG(OBEX_IRDATRANSPORT_ZONE,(L"CObexIRDATransport::CreateSocket()\n"));
   
    *ppSocket = new CIRDATransportSocket(); 
    if( !(*ppSocket) )
    {
        return E_OUTOFMEMORY;
    }
    return S_OK;
}


HRESULT STDMETHODCALLTYPE 
CObexIRDATransport::CreateSocketBlob(unsigned long ulSize,
                                     byte __RPC_FAR *pbData,
                                     LPSOCKET __RPC_FAR *ppSocket)
{
        return E_NOTIMPL;
}

HRESULT STDMETHODCALLTYPE 
CObexIRDATransport::EnumDevices(LPPROPERTYBAGENUM *ppDevices)
{
    DEBUGMSG(OBEX_IRDATRANSPORT_ZONE,(L"CObexIRDATransport::EnumDevices()\n"));
  
    //
    //  Because IRDA is very quick on enum we can end up spin locking 
    //    during query.  this limits the frequency of call to 500 ms
    //
    if(GetTickCount() - dwTimeOfLastEnum < 500)
    {
        DEBUGMSG(OBEX_IRDATRANSPORT_ZONE, (L"[OBEX] ObexIRDATransport::UpdateDeviceProperties() -- sleeping for a bit to avoid spinlock\n"));
        Sleep(500);        
    }
    dwTimeOfLastEnum = GetTickCount();
    
    //start by setting the enumeration to be 0 (error)
    *ppDevices = 0;

    //create a socket
    SOCKET s = socket(AF_IRDA, SOCK_STREAM, 0);
    if(s == INVALID_SOCKET) {        
        DEBUGMSG(OBEX_IRDATRANSPORT_ZONE,(L"CObexIRDATransport::EnumDevices() -- got an invalid socket\n"));
        SetLastError (ERROR_DEVICE_NOT_CONNECTED);
        return E_FAIL;
    }
    //memory to hold possible servers    
    unsigned char   DevListBuff[sizeof(DEVICELIST) -
        sizeof(IRDA_DEVICE_INFO) +
        (sizeof(IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
    
    int DevListLen   = sizeof(DevListBuff);
    PDEVICELIST   pDevList   = (PDEVICELIST)DevListBuff;
    pDevList->numDevice = 0;

    //search to see what IrDA devices are visible
    for(UINT uiTries=0; uiTries <= g_uiIRDAMaxRetries; uiTries ++)  {  
        int optReturn = getsockopt(s, 
                                   SOL_IRLMP, 
                                   IRLMP_ENUMDEVICES, 
                                   (char *) pDevList, 
                                   &DevListLen);        
                                   
        if (optReturn == SOCKET_ERROR)
        {
            int errorCode = WSAGetLastError();

            //if a blocking call is being made, just sleep and 
            //  try again, otherwise bail out
            if(WSAEINPROGRESS == errorCode)
            {
                DEBUGMSG(OBEX_IRDATRANSPORT_ZONE,(L"CObexIRDATransport::EnumDevices() -- error in progress.. trying again in 500 ms\n"));
 
                //clean out the structure so there is no
                //  confusion later (since it hasnt been inited
                //  by getsockopt)
                pDevList->numDevice = 0;
            
                //sleep for half a second to give the other
                // function time to finish up (note: this stinks
                // but there isnt anything we can do but wait it
                // out)             
                Sleep(500);

            }
            else
            {        
                closesocket(s);
                
                int err = WSAGetLastError();
                DEBUGMSG(OBEX_IRDATRANSPORT_ZONE, (L"Error code: %d\n", err));
                return E_FAIL;
            }
        } 
        if(pDevList->numDevice != 0)                      
            break;
       
    }
    
    
    CPropertyBagEnum *pPropEnum = new CPropertyBagEnum();
    
    if(!pPropEnum)
    {
        closesocket(s);        
        return E_OUTOFMEMORY;
    }
    
    CPropertyBag *pPropBag;
    HRESULT hr = S_OK;

    VARIANT var;
    VariantInit(&var);
    for(UINT i=0; i<pDevList->numDevice; i++)
    {    
        DEBUGMSG(OBEX_IRDATRANSPORT_ZONE,(L"CObexIRDATransport::EnumDevices() -- found %d devices\n", pDevList->numDevice));
 
        hr = S_OK;
        pPropBag = new CPropertyBag();
        
        if(NULL == pPropBag)
        {
            closesocket(s);
            pPropBag->Release();
            return E_OUTOFMEMORY;
        }


        // set the device ID
        var.vt = VT_I4;       
        memcpy((char *)&var.lVal, pDevList->Device[i].irdaDeviceID, 4);

        hr = pPropBag->Write(c_szDevicePropAddress, &var);
        SVSUTIL_ASSERT(SUCCEEDED(hr));

        DEBUGMSG(OBEX_IRDATRANSPORT_ZONE,(L"CObexIRDATransport::EnumDevices() -- filling in props for device\n"));
 

        // now the name
        WCHAR pszName[MAX_PATH];
        int nRet = MultiByteToWideChar(CP_ACP, 0, pDevList->Device[i].irdaDeviceName, -1, pszName, MAX_PATH);
        if ((nRet > 0) && (nRet < MAX_PATH))
        {
            VariantClear(&var);
            var.vt = VT_BSTR;
            var.bstrVal = SysAllocString(pszName);
            
            if(NULL == var.bstrVal)
            {
                closesocket(s);
                pPropBag->Release();
                return E_OUTOFMEMORY;
            }
        
            hr = pPropBag->Write(c_szDevicePropName, &var);            
            SVSUTIL_ASSERT(SUCCEEDED(hr));
        }
        
        // finally the transport ID
        LPOLESTR pszClsid = NULL;
        hr = StringFromCLSID((REFCLSID) CLSID_IrdaTransport, &pszClsid);
           SVSUTIL_ASSERT(SUCCEEDED(hr));
        VariantClear(&var);
        var.vt = VT_BSTR;
        var.bstrVal = SysAllocString(pszClsid); 
        CoTaskMemFree(pszClsid);
        
        hr = pPropBag->Write(c_szDevicePropTransport, &var);
        
        SVSUTIL_ASSERT(SUCCEEDED(hr));
 
        // add to the list
        pPropEnum->Insert(pPropBag);
        pPropBag->Release();
        VariantClear(&var);
    }
    
    
    *ppDevices = pPropEnum; 
    closesocket(s);
    return hr;
}


HRESULT STDMETHODCALLTYPE 
CObexIRDATransport::UpdateDeviceProperties(LPPROPERTYBAG2 __RPC_FAR pDevice, 
                                          IPropertyBagEnum **_ppNewBagEnum, 
                                          BOOL fGetJustEnoughToConnect, 
                                          UINT *uiUpdateStatus)
{ 
    DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE,(L"ObexIRDATransport::UpdateDeviceProperties()\n"));
    
    PREFAST_ASSERT(pDevice && uiUpdateStatus);
    
    //set the default error to return
    HRESULT hRet = E_FAIL;

    //variables 
    SOCKET sMySock = INVALID_SOCKET;
 
    BOOL fHaveIrXFer = FALSE;
    BOOL fHaveObex = FALSE;

    
    //fetch the device ID from the property bag
    VARIANT pDeviceVar;
    VARIANT pNameVar;
    VARIANT varMarkTest;
    
    VariantInit(&pDeviceVar);
    VariantInit(&pNameVar);
    VariantInit(&varMarkTest);    
    
    char pDeviceName[25];
    BOOL fAbort;

  
    //
    //  Do a test to see if we already have enough info (if we have been here)
    //
    if(SUCCEEDED(pDevice->Read(L"BeenVisited", &varMarkTest, 0)) &&
        1 == varMarkTest.lVal)
    {
        DEBUGMSG(OBEX_IRDATRANSPORT_ZONE, (L"[OBEX] ObexIRDATransport::UpdateDeviceProperties() -- already visited!\n"));
        *uiUpdateStatus = 0xFFFFFFFF;
        VariantClear(&varMarkTest);
        return S_OK;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -