Click here to Skip to main content
15,881,882 members
Articles / Mobile Apps / Windows Mobile

pfront: A utility for Windows Mobile

Rate me:
Please Sign up or sign in to vote.
4.50/5 (4 votes)
2 May 2011CPOL2 min read 16.7K   354   12  
A small addition to the popular command-line itsutils for Windows Mobile.
// pfront.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <atlbase.h>
#include <rapi2.h>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <fstream>
#include <iostream>

#pragma comment( lib, "rapiuuid.lib" )

// CopyToDevice
/// @brief Copy a file to the attached device if it does not already exist
/// @param session - open RAPI2 session
/// @param local_file - path to the local file
/// @param remote_file - path to the remote file
/// @return BOOL - TRUE on success
static BOOL CopyToDevice( IRAPISession* session, 
                          const wchar_t* local_src_file, 
                          const wchar_t* remote_dest_file )
{
    BOOL success = FALSE;

    // open the local file first
    std::ifstream local( local_src_file, std::ios_base::binary );
    if( local.is_open() )
    {
        // create the remote file if it doesn't already exist
        // must have BOOST_MEM_FN_ENABLE_STDCALL defined
        boost::shared_ptr< void > remote_file( 
            session->CeCreateFile( remote_dest_file,
                GENERIC_WRITE,
                0,
                NULL,
                CREATE_NEW,
                FILE_ATTRIBUTE_NORMAL,
                INVALID_HANDLE_VALUE ),
            boost::bind( &IRAPISession::CeCloseHandle, session, _1 ) );

        if( INVALID_HANDLE_VALUE != remote_file.get() )
        {
            char buffer[ 10 * 1024 ];
            DWORD bytes_written;
            
            // copy the local file to the dev
            while( local.good() )
            {
                local.read( buffer, sizeof( buffer ) );
                if( !session->CeWriteFile( remote_file.get(), 
                                           buffer, 
                                           local.gcount(), 
                                           &bytes_written, 
                                           NULL ) ) 
                {
                    break;
                }

                // we succeed if we successfully copy the entire file
                success = local.eof();
            }
        }
        else
        {
            // check to see if we failed because the file is already on the dev
            success = ( session->CeGetLastError() == ERROR_FILE_EXISTS );
        }
    }

    return success;
};

struct com
{
    com() { ::CoInitialize( NULL ); };
    ~com() { ::CoUninitialize(); };
};

struct ole
{
    ole() { ::OleInitialize( NULL ); };
    ~ole() { ::OleUninitialize(); };
};

#define WIDEN_INT(x) L ## x
#define WIDEN(x) WIDEN_INT(x)

#define CHECK( x ) { HRESULT _hr = x;                                         \
                     if( FAILED( _hr ) ) {                                    \
                     std::wcerr << L"Initialization failed."                  \
                     << std::endl << WIDEN( #x ) << L" = "                    \
                     << std::hex << _hr << std::endl << std::endl;            \
                     return _hr; } }

int _tmain( int argc, _TCHAR* argv[] )
{
    if( argc < 2 )
    {
        std::wcerr << L"Usage: pfront <executable_name.exe>" 
                   << std::endl 
                   << std::endl;
        return -1;
    }
    
    com c;
    ole o;

    {
        CComPtr< IRAPIDesktop > rapi_desktop;
        CHECK( rapi_desktop.CoCreateInstance( CLSID_RAPI ) )

        CComPtr< IRAPIEnumDevices > rapi_device_list;
        CHECK( rapi_desktop->EnumDevices( &rapi_device_list ) )

        CComPtr< IRAPIDevice > rapi_device;
        CHECK( rapi_device_list->Next( &rapi_device ) )

        CComPtr< IRAPISession > rapi_session;
        CHECK( rapi_device->CreateSession( &rapi_session ) )

        CHECK( rapi_session->CeRapiInit() )

        if( CopyToDevice( rapi_session, 
                          L".\\pfront_lib.dll", 
                          L"\\pfront_lib.dll" ) )
        {
            BYTE *unused_a = NULL;
            DWORD unused_b = 0;
            HRESULT hr = rapi_session->CeRapiInvoke( L"pfront_lib.dll",
                L"PFRONT_BringToFront",
                ( ::wcslen( argv[ 1 ] ) + 1 ) * sizeof( wchar_t ),
                reinterpret_cast< BYTE* >( argv[ 1 ] ),
                &unused_b,
                &unused_a,
                NULL,
                0 );
            if( hr == ERROR_FILE_NOT_FOUND )
            {
                std::wcerr << L"Unable to find " 
                           << argv[ 1 ] << L"."
                           << std::endl 
                           << std::endl;
            }
        }
        else
        {
            std::wcerr << L"Unable to upload pfront_lib.dll to the device." 
                       << std::endl 
                       << std::endl;
        }

        rapi_session->CeRapiUninit();
    }

	return 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) An engineering firm in Cedar Rapids, Iowa
United States United States
I'm also on the MSDN forums
http://social.msdn.microsoft.com/profile/paulh79

Comments and Discussions