Click here to Skip to main content
15,891,597 members
Articles / Mobile Apps / Windows Mobile

RAPI2: The Friend You Never Knew You Had

Rate me:
Please Sign up or sign in to vote.
4.74/5 (13 votes)
17 May 2010CPOL7 min read 41.5K   367   23  
Using the RAPI2 interface safely and effectively.
#pragma once
#include <iomanip>
#include <ctime>
#include <locale>

#define EPOCH_DIFF 0x019DB1DED53E8000LL /* 116444736000000000 nsecs */
#define RATE_DIFF 10000000 /* 100 nsecs */

/// convert from FILETIME to time_t 
time_t FileTimeToUnixTime( const FILETIME& ftime ) 
{
    LARGE_INTEGER ll = { ftime.dwLowDateTime, ftime.dwHighDateTime };
    return ( ll.QuadPart - EPOCH_DIFF ) / RATE_DIFF;
}

/// Get the 64-bit size of the file.
__int64 FileSize( const CE_FIND_DATA& i )
{
    return ( static_cast< __int64 >( i.nFileSizeHigh ) << 32 ) + i.nFileSizeLow;
}

/// ostream iterator formatting for CE_FIND_DATA
template< class _CharT = wchar_t, class _Traits = std::char_traits< _CharT > >
struct WinCeFindData
{
    typedef typename std::basic_ostream< _CharT, _Traits > stream_type;
    typedef WinCeFindData< _CharT, _Traits > _Self;

    WinCeFindData( const CE_FIND_DATA& data ) : data_( data ) {};

    friend stream_type& operator<<( stream_type& os, const _Self& item )
    {
        stream_type::sentry os_lock( os );
        if( !os_lock )
            return os;
        
        // print the creation date/time
        _CharT pattern[] = L"%m/%d/%Y  %I:%M %p  ";
        time_t universal_time = FileTimeToUnixTime( item.data_.ftCreationTime );
        tm local_time = { 0 };
        if( localtime_s( &local_time, &universal_time ) == 0 )
        {
            std::time_put< _CharT > const& time_facet = 
                std::use_facet< std::time_put< _CharT > >( os.getloc() );
            time_facet.put( os, 
                            os, 
                            L' ', 
                            &local_time, 
                            pattern, 
                            pattern + wcslen( pattern ) );
        }
        else
        {
            os << L"00/00/0000  00:00 AM  ";
        }

        os << std::setfill( L' ' );

        // print the file size or <DIR> for directories
        if( item.data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
            os << std::left 
               << std::setw( 14 ) 
               << L"<DIR>";
        else
            os << std::right 
               << std::setw( 14 ) 
               << FileSize( item.data_ );

        // print the file name
        os << L" " << item.data_.cFileName;
        return os;
    };

private:
    // local reference to the data being printed
    const CE_FIND_DATA& data_;
    // no assignment
    const _Self& operator=( const _Self& );
}; // struct WinCeFindData

/// determine if a particular item is a directory or not.
bool is_directory( const CE_FIND_DATA& data )
{
    return ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) != 0;
}

/// return true if i < j
bool descending( const CE_FIND_DATA& i, const CE_FIND_DATA& j )
{
    // we sort directories first, then by filename
    if( is_directory( i ) != is_directory( j ) )
        return is_directory( i );
    return _wcsicmp( i.cFileName, j.cFileName ) < 0;
}

/// add the file size of a CE_FIND_DATA
__int64 operator+( __int64 i, const CE_FIND_DATA& j )
{
    if( !is_directory( j ) )
        i += FileSize( j );
    return i;
}

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