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

📄 obexftp.cpp

📁 用MFC实现的在pocket PC之间通过红外技术通信的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        {
          return TRUE;
        }
        else
        {
          m_obex=NULL;
          ATLTRACE(_T("Cannot Advise!\n"));
        }
      }
      else
      {
        m_obex=NULL;
        ATLTRACE(_T("Cannot IObex::Initialize!\n"));
      }
    }
#ifdef _DEBUG
    else
    {
      ATLTRACE(_T("Cannot CoCreate IObex!\n"));
    }
#endif
  }
  return FALSE;
}
 
//-------------------------------------------------------------------
// CObexFTP::StartDeviceEnum - start asynchronous events via IObexSink
//-------------------------------------------------------------------
BOOL CObexFTP::StartDeviceEnumeration()
{
  if (!m_bEnumerating)
  {
    if (m_obex)
    {
      if (SUCCEEDED(m_obex->StartDeviceEnum()))
        m_bEnumerating=true;
    }
  }
  return m_bEnumerating;
}
//-------------------------------------------------------------------
// CObexFTP::StopDeviceEnum - stop asynchronous events via IObexSink
//-------------------------------------------------------------------
void CObexFTP::StopDeviceEnumeration()
{
  if (m_bEnumerating)
  {
    ATLASSERT((IObex *)m_obex);
    m_obex->StopDeviceEnum();
    m_bEnumerating=false;
  }
}

//-------------------------------------------------------------------
// CObexFTP::IObexSink::IUnknown::Addref - std implementation
//-------------------------------------------------------------------
ULONG CObexFTP::AddRef()
{
  ULONG cr=InterlockedIncrement(&m_cRef);
  return cr;
}
//-------------------------------------------------------------------
// CObexFTP::IObexSink::IUnknown::Release - std implementation
//-------------------------------------------------------------------
ULONG CObexFTP::Release()
{
  ULONG cr=InterlockedDecrement(&m_cRef);
  ATLASSERT(m_cRef);
  return cr;
}
//-------------------------------------------------------------------
// CObexFTP::IObexSink::IUnknown::QueryInterface - std implementation
//-------------------------------------------------------------------
HRESULT CObexFTP::QueryInterface(REFIID iid,void ** ppvObject)
{
	if (InlineIsEqualGUID(iid, IID_IObexSink) || 
			InlineIsEqualUnknown(iid))
	{
		if (ppvObject == NULL)
				return E_POINTER;
		*ppvObject = (void*)(IUnknown*)this;
		AddRef();
    return S_OK;
  }
  *ppvObject=NULL;
  return E_NOINTERFACE;
}

//-------------------------------------------------------------------
// CObexFTP::IObexSink::IUnknown::QueryInterface - std implementation
//-------------------------------------------------------------------
HRESULT CObexFTP::Notify(OBEX_EVENT Event,IUnknown* pUnk1,IUnknown* /*pUnk2*/)
{
  // Create a helper object for property access
  CObexDeviceProperties dev(pUnk1);
  ATLASSERT((IPropertyBag *)dev);
  if (dev)
  {
    // build a unique key from Address+ServiceUUID
    CString Key=dev.GetAddress();
    Key+=dev.GetServices();
    // and determine if this device supports OBEX-FTP
    bool IsFTP=dev.CanFTP();
    // if it does - see if its already connected
    if (IsFTP)
    {
      CObexFTPConnection *pConn;
      pConn=FindConnection(Key);
      if (pConn)
      {
        // if yes - call the appropriate handler
        ATLASSERT(Event!=OE_DEVICE_ARRIVAL);
        if (Event==OE_DEVICE_UPDATE)
          OnDeviceChange(pConn,dev);
        else
          OnDeviceRemoval(pConn);
      }
      else if (Event!=OE_DEVICE_DEPARTURE)
      {
        // no this a new one
        OnDeviceArrived(dev);
      }
    }
  }
  return S_OK;
}

//-------------------------------------------------------------------
// CObexFTP::OnDeviceArrived - should be overridden !
//-------------------------------------------------------------------
void CObexFTP::OnDeviceArrived(IPropertyBag *Bag)
{
}

//-------------------------------------------------------------------
// CObexFTP::OnDeviceRemoval - call pConn->OnDeviceRemoval
//-------------------------------------------------------------------
void CObexFTP::OnDeviceRemoval(CObexFTPConnection *pConn)
{
  ATLASSERT(pConn);
  if (pConn)
    pConn->OnDeviceRemoval();
}
//-------------------------------------------------------------------
// CObexFTP::OnDeviceChange - call pConn->OnDeviceChange
//-------------------------------------------------------------------
void CObexFTP::OnDeviceChange(CObexFTPConnection *pConn,IPropertyBag *Prop)
{
  ATLASSERT(pConn);
  if (pConn)
    pConn->OnDeviceChange(Prop);
}

// This is the ServiceUUID of the Obex-FTP in network order
GUID CLSID_FileExchange_NetOrder =	// {F9ec7bc4-953c-11d2-984e-525400dc9e09}
{ 0xc47becf9, 0x3c95, 0xd211, {0x98, 0x4e, 0x52, 0x54, 0x00, 0xdc, 0x9e, 0x09}};

//-------------------------------------------------------------------
// CObexFTP::Connect() - called only from friend CObexFTPConnection
//-------------------------------------------------------------------
BOOL CObexFTP::Connect(CObexFTPConnection *pConn,IPropertyBag *Prop,IObexDevice **ppOut)
{
  // first we must bind the properties to a device
  if (m_obex)
  {
    CComPtr<IObexDevice> Dev;
    if (SUCCEEDED(m_obex->BindToDevice(Prop,&Dev)))
    {
      // Set the password if required
      const CString &Password=pConn->GetPassword();
      if (!Password.IsEmpty())
        Dev->SetPassword(Password);
      // then connect to proper Service
      CComPtr<IHeaderCollection> Coll;
      if (SUCCEEDED(Coll.CoCreateInstance(__uuidof(HeaderCollection))))
      {
         if (SUCCEEDED(Coll->AddTarget(sizeof(CLSID_FileExchange_NetOrder),(BYTE *)&CLSID_FileExchange_NetOrder)))
         {
           // Question: do we need the password here, if it's already set in SetPassword ?
           //           is the dwCap parameter of any interest for any server ?
           if (SUCCEEDED(Dev->Connect(Password,OBEX_DEVICE_CAP_FILE_BROWSE,Coll)))
           {
             // NOTE: may be SUCCEDED is not enough; WINCE samples re-enumerate the HeaderCollection,
             // try to find a CONNECTION_ID-Header and only report success if it is found ?
             *ppOut=Dev.Detach();
             // build the unique key
             CObexDeviceProperties odp(Prop);
             CString Key=odp.GetAddress();
             Key+=odp.GetServices();
             pConn->SetKey(Key);
             // and add to our active list
             AddConnection(pConn);
             return TRUE;
           }
         }
      }
    }
  }
  return FALSE;
}

BOOL CObexFTP::Disconnect(CObexFTPConnection *pConn)
{
  // simply unlink from our list of connections
  return m_Connections.Unlink(pConn)!=NULL;
}

//-------------------------------------------------------------------
// CObexFTP::ConnectTo 
//  use this function if you do not want to use derived classes
//  for CObexFTPConnection
//-------------------------------------------------------------------
CObexFTPConnection *CObexFTP::ConnectTo(IPropertyBag *Prop,LPCWSTR pszPassw/*=NULL*/)
{
  CObexFTPConnection *pConn=new CObexFTPConnection(pszPassw);
  if (!pConn->Connect(this,Prop))
  {
    delete pConn;
    pConn=NULL;
  }
  return pConn;
}

//-------------------------------------------------------------------
// CObexFTP::Connect management: find a connection with unique id
//-------------------------------------------------------------------
CObexFTPConnection *CObexFTP::FindConnection(const CString &Key)
{
  return m_Connections.Find(Key);
}
//-------------------------------------------------------------------
// CObexFTP::Connect management: add a connection to the list
//-------------------------------------------------------------------
void CObexFTP::AddConnection(CObexFTPConnection *pConn)
{
  m_Connections.Push(pConn);
}


//-------------------------------------------------------------------
// CObexFTPConnection ctor
// the optional password is used during connect if the server
// requires this
//-------------------------------------------------------------------
CObexFTPConnection::CObexFTPConnection(LPCWSTR pszPassw/*=NULL*/)
: m_strPassw(pszPassw),m_pNext(NULL),m_pObj(NULL)
{
}
//-------------------------------------------------------------------
// CObexFTPConnection dtor
//-------------------------------------------------------------------
CObexFTPConnection::~CObexFTPConnection()
{
  // if still connected, disconnect
  Disconnect();
}
//-------------------------------------------------------------------
// CObexFTPConnection::OnDeviceRemoval
// should be overwritten to cancel operation an close
//-------------------------------------------------------------------
void CObexFTPConnection::OnDeviceRemoval()
{
}
//-------------------------------------------------------------------
// CObexFTPConnection::OnDeviceChange
// could be overwritten to reread saved properties etc.
//-------------------------------------------------------------------
void CObexFTPConnection::OnDeviceChange(IPropertyBag* /*Bag*/)
{
}

//-------------------------------------------------------------------
// CObexFTPConnection::GetDeviceName
// ask the device for its propertybag and the query the name
//-------------------------------------------------------------------
CString CObexFTPConnection::GetDeviceName()
{
  CObexDeviceProperties Prop(m_device);
  return Prop.GetName();
}

//-------------------------------------------------------------------
// CObexFTPConnection::Connect
// typically called in CObexFTP::OnDeviceArrived
// call CObexFTP::Connect to do the work
//-------------------------------------------------------------------
BOOL CObexFTPConnection::Connect(CObexFTP *pObj,IPropertyBag *Bag)
{
  if (pObj->Connect(this,Bag,&m_device))
  {
    m_pObj=pObj;
    return TRUE;
  }
  return FALSE;
}
//-------------------------------------------------------------------
// CObexFTPConnection::Disconnect
// call this function if you are done with the connection
// only delete a connection after Disconnect!
//-------------------------------------------------------------------
CObexFTPConnection *CObexFTPConnection::Disconnect(bool bAutoDel/*=false*/)
{
  if (m_device)
  {
    CComPtr<IHeaderCollection> Coll;
    Coll.CoCreateInstance(__uuidof(HeaderCollection));
    m_device->Disconnect(Coll);
    m_device=NULL;
  }
  if (m_pObj)
  {
    CObexFTP *pParent=m_pObj;
    m_pObj=NULL;
    pParent->Disconnect(this);
  }
  if (bAutoDel)
  {
    delete this;
    return NULL;
  }
  return this;
}

//-------------------------------------------------------------------
// CObexFTPConnection::SetPath - set the Server-Path
// NOTE: the server path is always relative so pszPath cannot contain
//       \\ characters! you can use NULL to go back to the root or use
//       dwFlags=SETPATH_FLAG_BACKUP to simulate a cd ..
//       use dwFlags=SETPATH_FLAG_DONT_CREATE if you only want to read
//-------------------------------------------------------------------
BOOL CObexFTPConnection::SetPath(LPCWSTR pszPath,DWORD dwFlags/*=0*/)
{
  if (m_device)
    return SUCCEEDED(m_device->SetPath(pszPath,dwFlags,NULL));
  else
    return FALSE;
}
//-------------------------------------------------------------------
// CObexFTPConnection::GetFile - get a file from the current server
//       path and store it in a Memory file
//       use SetPath before for nested folders
//-------------------------------------------------------------------
BOOL CObexFTPConnection::GetFile(LPCWSTR pszName,CStreamToMemory &Mem)
{
  if (m_device)
  {
    return GetFileOrDir(pszName,NULL,Mem);
  }
  else
  {
    return FALSE;
  }
}
//-------------------------------------------------------------------
// CObexFTPConnection::PutFile - send data as a file to the current 
//       server path 
//       use SetPath before for nested folders
//-------------------------------------------------------------------
BOOL CObexFTPConnection::PutFile(LPCWSTR pszName,void *Data,UINT Size)
{
  if (m_device)
  {
    CComPtr<IHeaderCollection> Coll;
    if (SUCCEEDED(Coll.CoCreateInstance(__uuidof(HeaderCollection))))
    {
      if (SUCCEEDED(Coll->AddName(pszName)) &&
          SUCCEEDED(Coll->AddLength(Size)))
      {
        CComPtr<IStream> Stream;
        if (SUCCEEDED(m_device->Put(Coll,&Stream)))
        {
          DWORD Written=0;
          if (SUCCEEDED(Stream->Write(Data,Size,&Written)) &&
              SUCCEEDED(Stream->Commit(0)))
          {
            return TRUE;
          }
        }
      }
    }
  }
  return FALSE;
}
//-------------------------------------------------------------------
// CObexFTPConnection::GetDirectory - retrieve the content of the
//       current server path 
//       use SetPath before for nested folders
//       see member FindFirstFile, FindNextFile of CObexListing
//-------------------------------------------------------------------
BOOL CObexFTPConnection::GetDirectory(CObexListing &Dir)
{
  if (m_device)
  {
    return GetFileOrDir(_T(""),"x-obex/folder-listing",Dir);
  }
  else
  {
    return FALSE;
  }
}
//-------------------------------------------------------------------
// CObexFTPConnection::GetFileOrDir 
//    helper function for GetFile and GetDirectory
//-------------------------------------------------------------------
BOOL CObexFTPConnection::GetFileOrDir(LPCWSTR pszName,const char *mime,CStreamToMemory &Mem)
{
  ATLASSERT(m_device);
  CComPtr<IHeaderCollection> Coll;
  if (SUCCEEDED(Coll.CoCreateInstance(__uuidof(HeaderCollection))))
  {
    if (SUCCEEDED(Coll->AddName(pszName)))
    {
      int mime_len=mime ? strlen(mime) : 0;
      if (mime_len==0 || SUCCEEDED(Coll->AddType(mime_len+1,(BYTE *)mime)))
      {
        CComPtr<IStream> Stream;
        if (SUCCEEDED(m_device->Get(Coll,&Stream)))
        {
          return Mem.Read(Stream);
        }
      }
    }
  }
  return FALSE;
}

⌨️ 快捷键说明

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