Changeset 226


Ignore:
Timestamp:
04/05/11 15:01:41 (13 years ago)
Author:
tim
Message:

several fixes for pyregfi Windows portability
better error handling within pyregfi

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • SConstruct

    r225 r226  
    1 cflags = '-std=gnu99 -pedantic -Wall'
     1cflags = '-std=gnu99 -pedantic -Wall -D_FILE_OFFSET_BITS=64 -DREGFI_WIN32'
    22
    33libiconv_path='win32/libiconv/'
     
    100100                regfi_obj.append(s[0:-1]+'o')
    101101
     102            # XXX: Several options here may not be necessary. 
     103            #      Need to investigate why stdcall interfaces don't seem to be
     104            #      working on Windows.
    102105            env.Command(input_prefix+'lib/libregfi.o', regfi_o+extra_obj,
    103106                        'i586-mingw32msvc-dlltool --export-all-symbols'
    104                         +' --dllname libregfi.dll -e $TARGET'
     107                        +' --add-stdcall-alias  --dllname libregfi.dll -e $TARGET'
    105108                        +' -l %slib/libregfi.dll.a %s'
    106109                        % (input_prefix, ' '.join(regfi_obj)))
     
    108111            env.Command(input_prefix+'lib/libregfi.dll',
    109112                        input_prefix+'lib/libregfi.o',
    110                         'i586-mingw32msvc-gcc --shared -o $TARGET $SOURCE %s'
     113                        'i586-mingw32msvc-gcc ' + cflags
     114                        + ' --shared -Wl,--out-implib -add-stdcall-alias -o $TARGET $SOURCE %s'
    111115                        % ' '.join(regfi_obj+extra_obj))
    112116
  • trunk/include/regfi.h

    r224 r226  
    8484#undef _EXPORT
    8585#endif
     86#ifdef REGFI_WIN32
     87#define _EXPORT __declspec(dllexport)
     88#else
    8689#define _EXPORT __attribute__((visibility("default")))
    87 
    88 
     90#endif
     91
     92#ifndef EOVERFLOW
     93# define EOVERFLOW E2BIG
     94#endif
    8995
    9096/******************************************************************************/
     
    709715typedef struct _regfi_raw_file
    710716{
    711   off_t    (* seek)(); /* (REGFI_RAW_FILE* self, off_t offset, int whence) */
     717  int64_t  (* seek)(); /* (REGFI_RAW_FILE* self, uint64_t offset, int whence) */
    712718  ssize_t  (* read)(); /* (REGFI_RAW_FILE* self, void* buf, size_t count) */
    713719
     
    16271633/*    Private (and undocumented) Functions                                    */
    16281634/******************************************************************************/
    1629 off_t                 regfi_raw_seek(REGFI_RAW_FILE* self,
    1630                                      off_t offset, int whence);
     1635int64_t               regfi_raw_seek(REGFI_RAW_FILE* self,
     1636                                     uint64_t offset, int whence);
    16311637ssize_t               regfi_raw_read(REGFI_RAW_FILE* self,
    16321638                                     void* buf, size_t count);
    16331639_EXPORT
    1634 off_t                 regfi_seek(REGFI_RAW_FILE* file_cb,
    1635                                  off_t offset, int whence);
     1640uint64_t              regfi_seek(REGFI_RAW_FILE* file_cb,
     1641                                 uint64_t offset, int whence);
    16361642_EXPORT
    16371643uint32_t              regfi_read(REGFI_RAW_FILE* file_cb,
  • trunk/lib/regfi.c

    r225 r226  
    573573
    574574
    575 off_t regfi_raw_seek(REGFI_RAW_FILE* self, off_t offset, int whence)
    576 {
     575int64_t regfi_raw_seek(REGFI_RAW_FILE* self, uint64_t offset, int whence)
     576{
     577  if(sizeof(off_t) == 4 && offset > 2147483647)
     578  {
     579    errno = EOVERFLOW;
     580    return -1;
     581  }
    577582  return lseek(*(int*)self->state, offset, whence);
    578583}
     
    587592 * Convenience function to wrap up the ugly callback stuff
    588593 *****************************************************************************/
    589 off_t regfi_seek(REGFI_RAW_FILE* file_cb, off_t offset, int whence)
     594uint64_t regfi_seek(REGFI_RAW_FILE* file_cb, uint64_t offset, int whence)
    590595{
    591596  return file_cb->seek(file_cb, offset, whence);
     
    15611566  REGFI_HBIN* hbin = NULL;
    15621567  uint32_t hbin_off, cache_secret;
    1563   int32_t file_length;
     1568  int64_t file_length;
    15641569  bool rla;
    15651570
     
    15671572   * and one hbin.
    15681573   */
    1569   file_length = file_cb->seek(file_cb, 0, SEEK_END);
     1574  file_length = regfi_seek(file_cb, 0, SEEK_END);
    15701575  if(file_length < REGFI_REGF_SIZE+REGFI_HBIN_ALLOC)
    15711576  {
     
    15741579    return NULL;
    15751580  }
    1576   file_cb->seek(file_cb, 0, SEEK_SET);
     1581  regfi_seek(file_cb, 0, SEEK_SET);
    15771582
    15781583  if(output_encoding != REGFI_ENCODING_UTF8
  • trunk/python/pyregfi/__init__.py

    r225 r226  
    177177def GetLogMessages():
    178178    msgs = regfi.regfi_log_get_str()
    179     if msgs == None:
     179    if not msgs:
    180180        return ''
    181181    return msgs.decode('utf-8')
     
    625625    # @note Supplied file must be seekable
    626626    def __init__(self, fh):
     627        # The fileno method may not exist, or it may throw an exception
     628        # when called if the file isn't backed with a descriptor.
     629        fn = None
    627630        try:
    628             # The fileno method may not exist, or it may throw an exception
    629             # when called if the file isn't backed with a descriptor.
    630             if hasattr(fh, 'fileno'):
    631                 self.file = regfi.regfi_alloc(fh.fileno(), REGFI_ENCODING_UTF8)
    632                 return
     631            # XXX: Native calls to Windows filenos don't seem to work. 
     632            #      Need to investigate why.
     633            if not is_win32 and hasattr(fh, 'fileno'):
     634                fn = fh.fileno()
    633635        except:
    634636            pass
    635        
    636         fh.seek(0)
    637         self.raw_file = structures.REGFI_RAW_FILE()
    638         self.raw_file.fh = fh
    639         self.raw_file.seek = seek_cb_type(self.raw_file.cb_seek)
    640         self.raw_file.read = read_cb_type(self.raw_file.cb_read)
    641         self.file = regfi.regfi_alloc_cb(pointer(self.raw_file), REGFI_ENCODING_UTF8)
    642         if not self.file:
    643             # XXX: switch to non-generic exception
    644             raise Exception("Could not open registry file.  Current log:\n"
    645                             + GetLogMessages())
     637
     638        if fn != None:
     639            self.file = regfi.regfi_alloc(fn, REGFI_ENCODING_UTF8)
     640            if not self.file:
     641                # XXX: switch to non-generic exception
     642                raise Exception("Could not open registry file.  Current log:\n"
     643                                + GetLogMessages())
     644        else:
     645            fh.seek(0)
     646            self.raw_file = structures.REGFI_RAW_FILE()
     647            self.raw_file.fh = fh
     648            self.raw_file.seek = seek_cb_type(self.raw_file.cb_seek)
     649            self.raw_file.read = read_cb_type(self.raw_file.cb_read)
     650            self.file = regfi.regfi_alloc_cb(pointer(self.raw_file), REGFI_ENCODING_UTF8)
     651            if not self.file:
     652                # XXX: switch to non-generic exception
     653                raise Exception("Could not open registry file.  Current log:\n"
     654                                + GetLogMessages())
     655
    646656
    647657    def __getattr__(self, name):
     
    703713    def __init__(self, hive):
    704714        self._iter = regfi.regfi_iterator_new(hive.file, REGFI_ENCODING_UTF8)
    705         if self._iter == None:
     715        if not self._iter:
    706716            raise Exception("Could not create iterator.  Current log:\n"
    707717                            + GetLogMessages())
  • trunk/python/pyregfi/structures.py

    r225 r226  
    1313from ctypes import *
    1414
     15is_win32 = hasattr(ctypes, 'windll')
    1516
    1617# XXX: can we always be sure enums are this size?
     
    6162        except Exception:
    6263            traceback.print_exc()
    63             # XXX: os.EX_IOERR may not be available on Windoze
    64             set_errno(os.EX_IOERR)
     64            set_errno(74) # os.EX_IOERR
    6565            return -1
    6666
     
    7676        except Exception:
    7777            traceback.print_exc()
    78             # XXX: os.EX_IOERR may not be available on Windoze
    79             set_errno(os.EX_IOERR)
     78            set_errno(74) # os.EX_IOERR
    8079            return -1
    8180        return len(tmp)
     
    8483# Load libregfi according to platform
    8584regfi = None
    86 if hasattr(ctypes, 'windll'):
     85if is_win32:
     86    # XXX: Using C calling conventions on cross-compiled DLLs seems to work fine
     87    #      on Windows, but I'm not sure if stdcall symbols are supported
     88    #      correctly for native Windows binaries...
    8789    #regfi = ctypes.windll.libregfi
    88     regfi = ctypes.WinDLL('libregfi.dll', use_errno=True)
    89     CB_FACTORY = ctypes.WINFUNCTYPE
     90    #CB_FACTORY = ctypes.WINFUNCTYPE
     91    regfi = ctypes.CDLL('libregfi.dll', use_errno=True)
     92    CB_FACTORY = ctypes.CFUNCTYPE
    9093else:
    9194    regfi = ctypes.CDLL(ctypes.util.find_library('regfi'), use_errno=True)
    9295    CB_FACTORY = ctypes.CFUNCTYPE
    9396
    94 # XXX: how can we know for sure the size of off_t? 
    95 #      -D_FILE_OFFSET_BITS=64 might help, need to research this
    96 #      Also, may need to use something like ctypes_configure
    97 #seek_cb_type = CB_FACTORY(c_int64, POINTER(REGFI_RAW_FILE), c_uint64, c_int, use_errno=True)
    98 seek_cb_type = CB_FACTORY(c_int64, POINTER(REGFI_RAW_FILE), c_uint64, c_int)
    99 #read_cb_type = CB_FACTORY(c_int64, POINTER(REGFI_RAW_FILE), POINTER(c_char), c_size_t, use_errno=True)
    100 read_cb_type = CB_FACTORY(c_int64, POINTER(REGFI_RAW_FILE), POINTER(c_char), c_size_t)
     97seek_cb_type = CB_FACTORY(c_int64, POINTER(REGFI_RAW_FILE), c_uint64, c_int, use_errno=True)
     98read_cb_type = CB_FACTORY(c_int64, POINTER(REGFI_RAW_FILE), POINTER(c_char), c_size_t, use_errno=True)
    10199
    102100
Note: See TracChangeset for help on using the changeset viewer.