Hey Everyone,

Just thought I'd upload our latest RAPI code that implements a file like object for reading and writing over RAPI. Hope you all find it helpful! Currently, it doesn't support the readline and iterator type thing, though that should be doable on top of this interface. Just didn't have time to tackle that piece when I was writing it.

Enjoy!
-Shane & Brian


#!/usr/bin/env python
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
##~ Copyright (C) 2002-2005  TechGame Networks, LLC.              ##
##~                                                               ##
##~ This library is free software; you can redistribute it        ##
##~ and/or modify it under the terms of the BSD style License as  ##
##~ found in the LICENSE file included with this distribution.    ##
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~ Imports 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

import os
from ctypes import windll, FormatError, sizeof, byref 
from ctypes import c_buffer, c_ulong, c_char, c_wchar, Structure, POINTER

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~ Constants / Variables / Etc. 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

INVALID_HANDLE_VALUE        = -1

GENERIC_EXECUTE             = 0x20000000
GENERIC_WRITE               = 0x40000000
GENERIC_READ                =-0x80000000

CREATE_NEW                  = 0x1
CREATE_ALWAYS               = 0x2
OPEN_EXISTING               = 0x3
OPEN_ALWAYS                 = 0x4

FILE_SHARE_READ             = 0x1
FILE_SHARE_WRITE            = 0x2
FILE_SHARE_DELETE           = 0x4

FILE_FLAG_POSIX_SEMANTICS   = 0x01000000
FILE_FLAG_BACKUP_SEMANTICS  = 0x02000000
FILE_FLAG_DELETE_ON_CLOSE   = 0x04000000
FILE_FLAG_SEQUENTIAL_SCAN   = 0x08000000
FILE_FLAG_RANDOM_ACCESS     = 0x10000000
FILE_FLAG_NO_BUFFERING      = 0x20000000
FILE_FLAG_OVERLAPPED        = 0x40000000
FILE_FLAG_WRITE_THROUGH     =-0x80000000

FILE_ATTRIBUTE_READONLY     = 0x0001
FILE_ATTRIBUTE_HIDDEN       = 0x0002
FILE_ATTRIBUTE_SYSTEM       = 0x0004
FILE_ATTRIBUTE_DIRECTORY    = 0x0010
FILE_ATTRIBUTE_ARCHIVE      = 0x0020
FILE_ATTRIBUTE_NORMAL       = 0x0080
FILE_ATTRIBUTE_TEMPORARY    = 0x0100
FILE_ATTRIBUTE_COMPRESSED   = 0x0800
FILE_ATTRIBUTE_OFFLINE      = 0x1000

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~ WinCE File-like object
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class CEFile(object):
    name = None
    mode = None
    closed = True
    newlines = None
    softspace = 0
    raiseErrors = True

    _flagShare = FILE_SHARE_READ
    _flagAttribute = FILE_ATTRIBUTE_NORMAL
    _flagWriteThrough = 0

    def __init__(self, name, mode='rU', buffering=None):
        self._loadRapiMethods()

        mode = mode.lower()
        self.name = name
        self.mode = mode
        if buffering == 0:
            self._flagWriteThrough = 1

        if 'u' in mode: 
            self.newlines = ['\r\n']

        if 'a' in mode:
            openMethod = self._openAppend
            fileAccessMode = GENERIC_WRITE
        elif 'w' in mode:
            openMethod = self._openWrite
            fileAccessMode = GENERIC_WRITE
        elif 'r' in mode:
            openMethod = self._openRead
            fileAccessMode = GENERIC_READ

        if '+' in mode: 
            fileAccessMode = GENERIC_READ | GENERIC_WRITE

        self._handle = openMethod(name, fileAccessMode)
        self.closed = False

    def __repr__(self):
        return "<%s.%s '%s', mode '%s' at 0x%x>" % (
                self.__class__.__module__, self.__class__.__name__,
                self.name, self.mode, id(self))

    _isCELoaded = False
    @classmethod
    def _loadRapiMethods(klass):
        if klass._isCELoaded:
            return True
        rapi = windll.rapi

        klass._CeGetLastError_ = staticmethod(rapi.CeGetLastError)

        def CeErrorCheck(result, cfunc, args):
            ceErrorNo = klass._CeGetLastError_()
            if ceErrorNo and ceErrorNo != 183:
                if klass.raiseErrors:
                    raise IOError('%s %d (0x%x)' % (FormatError(ceErrorNo), ceErrorNo, ceErrorNo))
                else:
                    print IOError('%s %d (0x%x)' % (FormatError(ceErrorNo), ceErrorNo, ceErrorNo))
            return result

        klass._CeCreateFile_ = staticmethod(rapi.CeCreateFile)
        klass._CeCreateFile_.errcheck = CeErrorCheck

        klass._CeCloseHandle_ = staticmethod(rapi.CeCloseHandle)
        klass._CeCloseHandle_.errcheck = CeErrorCheck

        klass._CeSetFilePointer_ = staticmethod(rapi.CeSetFilePointer)
        klass._CeSetFilePointer_.errcheck = CeErrorCheck

        klass._CeGetFileSize_ = staticmethod(rapi.CeGetFileSize)
        klass._CeGetFileSize_.errcheck = CeErrorCheck

        klass._CeReadFile_ = staticmethod(rapi.CeReadFile)
        klass._CeReadFile_.errcheck = CeErrorCheck

        klass._CeWriteFile_ = staticmethod(rapi.CeWriteFile)
        klass._CeWriteFile_.errcheck = CeErrorCheck

        klass._CeSetEndOfFile_ = staticmethod(rapi.CeSetEndOfFile)
        klass._CeSetEndOfFile_.errcheck = CeErrorCheck

        klass._isCELoaded = True
        return True

    def _openRead(self, name, fileAccessMode=GENERIC_READ):
        hceFile = self._CeCreateFile_(
                unicode(name),
                fileAccessMode,
                self._flagShare,
                None,
                OPEN_EXISTING,
                self._flagAttribute,
                self._flagWriteThrough and FILE_FLAG_WRITE_THROUGH or 0)
        if hceFile == INVALID_HANDLE_VALUE:
            raise IOError("Error opening the file on the device for reading")
        return hceFile
    def _openAppend(self, name, fileAccessMode=GENERIC_WRITE):
        hceFile = self._CeCreateFile_(
                unicode(name),
                fileAccessMode, 
                self._flagShare,
                None,
                OPEN_ALWAYS,
                self._flagAttribute,
                self._flagWriteThrough and FILE_FLAG_WRITE_THROUGH or 0)
        if hceFile == INVALID_HANDLE_VALUE:
            raise IOError("Error opening file on the device for appending")
        return hceFile
    def _openWrite(self, name, fileAccessMode=GENERIC_WRITE):
        hceFile = self._CeCreateFile_(
                unicode(name),
                GENERIC_WRITE,
                self._flagShare,
                None,
                CREATE_ALWAYS,
                self._flagAttribute,
                self._flagWriteThrough and FILE_FLAG_WRITE_THROUGH or 0)
        if hceFile == INVALID_HANDLE_VALUE:
            raise IOError("Error opening file on the device for writing")
        return hceFile

    def close(self):
        self._CeCloseHandle_(self._getHandle())
        self._handle = None
        self.closed = True

    def isatty(self):
        return False
    def fileno(self):
        return None

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    def tell(self):
        return self.seek(0, 1)
    def seek(self, pos, whence=0):
        result = self._CeSetFilePointer_(self._getHandle(), pos, None, whence)
        if result == 0xffffffff:
            raise IOError('CE Seek Error')
        return result

    def flush(self,):
        pass

    def read(self, count=None):
        handle = self._getHandle()
        if count is None:
            count = self._CeGetFileSize_(handle, None)
        data = c_buffer(count)
        dwRead = c_ulong(0)
        self._CeReadFile_(handle, data, len(data), byref(dwRead), None)
        data = data[:dwRead.value]

        if self.newlines:
            for n in self.newlines:
                data = data.replace(n, '\n')
        return data

    def writelines(self, lines):
        for line in lines:
            self.write(line + '\n') 

    def write(self, data):
        if not data: return
        dwWritten = c_ulong(0)
        self._CeWriteFile_(self._getHandle(), data, len(data), byref(dwWritten), None)

    def truncate(self, size=None):
        self._CeSetEndOfFile_(self._getHandle())

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    def _getHandle(self):
        handle = self._handle
        if handle is None or self.closed:
            raise IOError("CE file handle is closed")
        return handle
        

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~ Main 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if __name__=='__main__':
    from pocketRapi import PocketRapi
    pr = PocketRapi()
    f = CEFile('/testfile.txt', 'a+u')
    print repr(f.read())
    print >> f, 'test string!'
    print >> f, 'left',
    print >> f, 'right'

    print f.tell(), f.seek(0)
    print repr(f.read())
    print f.seek(0), f.seek(0, 2)
    print repr(f.read())
    f.close()


##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
##~ Copyright (C) 2002-2005  TechGame Networks, LLC.              ##
##~                                                               ##
##~ This library is free software; you can redistribute it        ##
##~ and/or modify it under the terms of the BSD style License as  ##
##~ found in the LICENSE file included with this distribution.    ##
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~ Imports 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

import StringIO
from ctypes import windll, FormatError, sizeof, byref 
from ctypes import c_buffer, c_ulong, c_char, c_wchar, Structure, POINTER

from ceFile import CEFile

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~ Constants / Variables / Etc. 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

INVALID_HANDLE_VALUE        = -1

GENERIC_EXECUTE             = 0x20000000
GENERIC_WRITE               = 0x40000000
GENERIC_READ                =-0x80000000

CREATE_NEW                  = 0x1
CREATE_ALWAYS               = 0x2
OPEN_EXISTING               = 0x3
OPEN_ALWAYS                 = 0x4

FILE_SHARE_READ             = 0x1
FILE_SHARE_WRITE            = 0x2
FILE_SHARE_DELETE           = 0x4

FILE_FLAG_POSIX_SEMANTICS   = 0x01000000
FILE_FLAG_BACKUP_SEMANTICS  = 0x02000000
FILE_FLAG_DELETE_ON_CLOSE   = 0x04000000
FILE_FLAG_SEQUENTIAL_SCAN   = 0x08000000
FILE_FLAG_RANDOM_ACCESS     = 0x10000000
FILE_FLAG_NO_BUFFERING      = 0x20000000
FILE_FLAG_OVERLAPPED        = 0x40000000
FILE_FLAG_WRITE_THROUGH     =-0x80000000

FILE_ATTRIBUTE_READONLY     = 0x0001
FILE_ATTRIBUTE_HIDDEN       = 0x0002
FILE_ATTRIBUTE_SYSTEM       = 0x0004
FILE_ATTRIBUTE_DIRECTORY    = 0x0010
FILE_ATTRIBUTE_ARCHIVE      = 0x0020
FILE_ATTRIBUTE_NORMAL       = 0x0080
FILE_ATTRIBUTE_TEMPORARY    = 0x0100
FILE_ATTRIBUTE_COMPRESSED   = 0x0800
FILE_ATTRIBUTE_OFFLINE      = 0x1000

FAF_ATTRIBUTES               = 0x00000001;
FAF_CREATION_TIME            = 0x00000002;
FAF_LASTACCESS_TIME          = 0x00000004;
FAF_LASTWRITE_TIME           = 0x00000008;
FAF_SIZE_HIGH                = 0x00000010;
FAF_SIZE_LOW                 = 0x00000020;
FAF_OID                      = 0x00000040;
FAF_NAME                     = 0x00000080;

FAF_FLAG_COUNT               = 8;

FAF_ATTRIB_CHILDREN          = 0x00001000;
FAF_ATTRIB_NO_HIDDEN         = 0x00002000;
FAF_FOLDERS_ONLY             = 0x00004000;
FAF_NO_HIDDEN_SYS_ROMMODULES = 0x00008000;

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~ Definitions 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MAX_PATH = 260

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class RAPIINIT(Structure):
    _fields_ = [
        ('cbSize', c_ulong),
        ('heRapiInitEvent', c_ulong),
        ('hrRapiInit', c_ulong), ]

class FILETIME(Structure):
    _fields_ = [
        ('nTimeHigh', c_ulong),
        ('nTimeLow', c_ulong), ]

class CE_FIND_DATA(Structure):
    _fields_ = [
        ('dwFileAttributes', c_ulong),
        ('ftCreationTime', FILETIME),
        ('dwLastAccessTime', FILETIME),
        ('dwLastWriteTime', FILETIME),
        ('nFileSizeHigh', c_ulong),
        ('nFileSizeLow', c_ulong),
        ('dwOID', c_ulong),
        ('cFileName', c_wchar*MAX_PATH), ]

class PROCESS_INFORMATION(Structure):
    _fields_ = [
        ('hProcess', c_ulong), 
        ('hThread', c_ulong), 
        ('dwProcessId', c_ulong), 
        ('dwThreadId', c_ulong), ]

class CEFileEx(CEFile): 
    raiseErrors = False

class PocketRapi(object):
    blockSize=65536
    _rapiReady = False
    _heRapiInitEvent = None
    raiseErrors = False
    CEFile = CEFileEx

    def __init__(self, blocking=False):
        self._loadRapiMethods()
        if blocking is not None:
            self.init(blocking)

    def __nonzero__(self):
        return self.isReady()

    def init(self, blocking=False):
        if blocking:
            self._rapiReady = (self._CeRapiInit_() == 0) # S_OK == 0
            return self._rapiReady

        self._rapiReady = None
        args = RAPIINIT()
        args.cbSize = sizeof(args)
        self._CeRapiInitEx_(byref(args))
        if args.hrRapiInit == 0: # S_OK
            self._heRapiInitEvent = args.heRapiInitEvent
            return True
        else: return False

    _isCELoaded = False
    @classmethod
    def _loadRapiMethods(klass):
        if klass._isCELoaded:
            return True
        rapi = windll.rapi

        klass._CeGetLastError = staticmethod(rapi.CeGetLastError)

        def CeErrorCheck(result, cfunc, args):
            ceErrorNo = rapi.CeGetLastError()
            if ceErrorNo and ceErrorNo != 183:
                if klass.raiseErrors:
                    raise OSError('%s %d (0x%x)' % (FormatError(ceErrorNo), ceErrorNo, ceErrorNo))
                else:
                    print OSError('%s %d (0x%x)' % (FormatError(ceErrorNo), ceErrorNo, ceErrorNo))
            return result

        klass._CeCloseHandle_ = staticmethod(rapi.CeCloseHandle)
        klass._CeCloseHandle_.errcheck = CeErrorCheck

        klass._CeCreateDirectory_ = staticmethod(rapi.CeCreateDirectory)
        klass._CeCreateDirectory_.errcheck = CeErrorCheck

        klass._CeCreateFile_ = staticmethod(rapi.CeCreateFile)
        klass._CeCreateFile_.errcheck = CeErrorCheck

        klass._CeCreateProcess_ = staticmethod(rapi.CeCreateProcess)
        klass._CeCreateProcess_.errcheck = CeErrorCheck

        klass._CeDeleteFile_ = staticmethod(rapi.CeDeleteFile)
        klass._CeDeleteFile_.errcheck = CeErrorCheck

        klass._CeFindAllFiles_ = staticmethod(rapi.CeFindAllFiles)
        klass._CeFindAllFiles_.errcheck = CeErrorCheck

        klass._CeGetFileAttributes_ = staticmethod(rapi.CeGetFileAttributes)
        #klass._CeGetFileAttributes_.errcheck = CeErrorCheck

        klass._CeRapiFreeBuffer_ = staticmethod(rapi.CeRapiFreeBuffer)
        klass._CeRapiFreeBuffer_.errcheck = CeErrorCheck

        klass._CeRapiGetError_ = staticmethod(rapi.CeRapiGetError)
        klass._CeRapiGetError_.errcheck = CeErrorCheck

        klass._CeRapiInit_ = staticmethod(rapi.CeRapiInit)
        klass._CeRapiInit_.errcheck = CeErrorCheck

        klass._CeRapiInitEx_ = staticmethod(rapi.CeRapiInitEx)
        #klass._CeRapiInitEx_.errcheck = CeErrorCheck

        klass._CeRapiUninit_ = staticmethod(rapi.CeRapiUninit)
        #klass._CeRapiUninit_.errcheck = CeErrorCheck

        klass._CeReadFile_ = staticmethod(rapi.CeReadFile)
        klass._CeReadFile_.errcheck = CeErrorCheck

        klass._CeRemoveDirectory_ = staticmethod(rapi.CeRemoveDirectory)
        klass._CeRemoveDirectory_.errcheck = CeErrorCheck

        klass._CeWriteFile_ = staticmethod(rapi.CeWriteFile)
        klass._CeWriteFile_.errcheck = CeErrorCheck

        klass._isCELoaded = True
        return True

    def isReady(self, timeout=0):
        if not self._rapiReady and self._heRapiInitEvent:
            self.waitForInit(timeout)
        return bool(self._rapiReady)

    def waitForInit(self, timeout=0):
        if not self._heRapiInitEvent:
            raise OSError("Event not initialized")

        miliseconds = min(0, max(int(timeout*1000), 0x7fffffff))
        events = (c_ulong*1)(self._heRapiInitEvent)
        waitResult = self.user32().MsgWaitForMultipleObjects(len(events), events, False, miliseconds, 0)

        if waitResult == 0:
            self._heRapiInitEvent = None
            self._rapiReady = True
        return self._rapiReady

    def uninit(self):
        self._CeRapiUninit_()
        self._rapiReady = False

    def getRapiError(self):
        return self._CeGetLastError_() or None
    def getRapiErrorStr(self):
        return FormatError(self.getRapiError())

    def joinPath(self, *args):
        args = filter(None, args)
        return '\\'.join(args or '')

    @staticmethod
    def user32(): 
        return windll.user32

    @staticmethod
    def rapi(): 
        return windll.rapi

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    def rmFile(self, path):
        return self._CeDeleteFile_(unicode(path))

    def mkDir(self, path):
        return self._CeCreateDirectory_(unicode(path), None)
    def rmDir(self, path):
        return self._CeRemoveDirectory_(unicode(path))
    def rmTree(self, path):
        for entry in self.listFiles(path):
            if self.isFile(entry):
                self.rmFile(entry)
            elif self.isDir(entry):
                self.rmTree(entry)
            #else: # what the heck is it?
        self.rmDir(path)

    def listFiles(self, path, incAttrs=False):
        files = self.findFiles(self.joinPath(path, '*'), incAttrs)
        if incAttrs:
            return [(self.joinPath(path, p[0]),) + p[1:] for p in files]
        else:
            return [self.joinPath(path, p) for p in files]

    def findFiles(self, path, incAttrs=False):
        mask = FAF_NAME  # Fill in the filename field
        if incAttrs:
            mask |= FAF_ATTRIBUTES # fill in the attribute field
            mask |= FAF_SIZE_LOW | FAF_SIZE_HIGH

        result = []
        nCount = c_ulong(0)
        answer = POINTER(CE_FIND_DATA*32767)()
        try:
            self._CeFindAllFiles_(unicode(path), mask, byref(nCount), byref(answer))

            if answer:
                answer = answer[0] # deref the pointer
                for i in xrange(nCount.value):
                    a = answer[i]
                    if incAttrs:
                        result.append((a.cFileName, (a.nFileSizeHigh << 32) | a.nFileSizeLow, a.dwFileAttributes))
                    else:
                        result.append(a.cFileName)
        finally:
            # free the memory they allocated for us
            if answer:
                self._CeRapiFreeBuffer_(byref(answer))
        return result
    
    def copyFileToDevice(self, hostFile, toPath,):
        if isinstance(hostFile, (str, unicode)):
            hostFile = open(hostFile, 'rb')

        #HANDLE CeCreateFile(
        #            LPCWSTR lpFileName, 
        #            DWORD dwDesiredAccess, 
        #            DWORD dwShareMode, 
        #            LPSECURITY_ATTRIBUTES lpSecurityAttributes, 
        #            DWORD dwCreationDisposition, 
        #            DWORD dwFlagsAndAttributes, 
        #            HANDLE hTemplateFile); 

        hceFile = self._CeCreateFile_(unicode(toPath), GENERIC_WRITE, FILE_SHARE_READ, None, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
        if hceFile == INVALID_HANDLE_VALUE:
            raise OSError("Error creating file on the device")

        try:
            dwWritten = c_ulong(0)
            data = hostFile.read(self.blockSize)
            while data:
                while dwWritten.value < len(data):
                    dwWritten.value = 0
                    self._CeWriteFile_(hceFile, data, len(data), byref(dwWritten), None)
                    data = data[dwWritten.value:]

                dwWritten.value = 0
                data = hostFile.read(self.blockSize)
        finally:
            self._CeCloseHandle_(hceFile)

    def getAttrs(self, path):
        result = self._CeGetFileAttributes_(unicode(path))
        if result == -1: 
            return None
        else: return result
    def exists(self, path):
        return self.getAttrs(path) is not None
    def dirExists(self, path):
        #return self.isDir(path)
        self.isDir(path)
        return self.exists(path)
    def fileExists(self, path):
        #return self.isFile(path)
        self.isFile(path)
        return self.exists(path)
    def isDir(self, path):
        attr = self.getAttrs(path)
        if attr is None:
            #print ('isDir:', path, attr)
            return None
        #print ('isDir:', path, attr, bool(attr & FILE_ATTRIBUTE_DIRECTORY))
        return attr and (attr & FILE_ATTRIBUTE_DIRECTORY)
    def isFile(self, path):
        attr = self.getAttrs(path)
        if attr is None:
            #print ('isFile:', path, attr)
            return None
        #print ('isFile:', path, attr, not (attr & FILE_ATTRIBUTE_DIRECTORY))
        return attr and not (attr & FILE_ATTRIBUTE_DIRECTORY)

    def fileSize(self, path):
        for each in self.findFiles(path, True):
            return each[1]
        return None

    def readFile(self, fromPath):
        hostFile = StringIO.StringIO()
        self.copyFileFromDevice(fromPath, hostFile)
        hostFile.seek(0)
        return hostFile

    def copyFileFromDevice(self, fromPath, hostFile):
        if isinstance(hostFile, (str, unicode)):
            hostFile = open(hostFile, 'wb')

        hceFile = self._CeCreateFile_(unicode(fromPath), GENERIC_READ, FILE_SHARE_READ, None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
        if hceFile == INVALID_HANDLE_VALUE:
            raise OSError("Error opening the file on the device for reading")

        try:
            dwRead = c_ulong(1)
            data = (self.blockSize * c_char)()
            
            while dwRead.value:
                dwRead.value = 0
                self._CeReadFile_(hceFile, data, len(data), byref(dwRead), None)
                hostFile.write(data.raw[:dwRead.value])
        finally:
            self._CeCloseHandle_(hceFile)
        return hostFile
    
    def openFile(self, name, mode='rU', buffering=None):
        return self.CEFile(name, mode, buffering)

    def popenDevice(self, path, commandLine=u''):
        processInfo = PROCESS_INFORMATION()
        result = bool(self._CeCreateProcess_(unicode(path), unicode(commandLine), None, None, False, 0, None, None, None, byref(processInfo)))
        return result

Copyright (c) 2002-2004, TechGame Networks, LLC.
All rights reserved.

Redistribution and use in source and binary forms, with or without 
modification, are permitted 
provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, 
      this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright notice, 
      this list of conditions and the following disclaimer in the documentation 
and/or 
      other materials provided with the distribution.

    * Neither the name of TechGame Networks, LLC nor the names of its 
contributors may 
      be used to endorse or promote products derived from this software without 
specific 
      prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
ANY EXPRESS 
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY 
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
COPYRIGHT OWNER OR 
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
SERVICES; LOSS OF USE, 
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
LIABILITY, WHETHER 
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT 
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
_______________________________________________
PythonCE mailing list
PythonCE@python.org
http://mail.python.org/mailman/listinfo/pythonce

Reply via email to