/* Seeks a certain offset within the file object
 * Make sure to hold the GIL state before calling this function
 * Returns 1 if successful or -1 on error
 */
int pysmraw_file_object_seek_offset(
     PyObject *file_object,
     off64_t offset,
     int whence,
     libcerror_error_t **error )
{
	PyObject *argument_offset = NULL;
	PyObject *argument_whence = NULL;
	PyObject *method_name     = NULL;
	PyObject *method_result   = NULL;
	static char *function     = "pysmraw_file_object_seek_offset";

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
#if defined( HAVE_LONG_LONG )
	if( offset > (off64_t) INT64_MAX )
#else
	if( offset > (off64_t) LONG_MAX )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid offset value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( ( whence != SEEK_CUR )
	 && ( whence != SEEK_END )
	 && ( whence != SEEK_SET ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported whence.",
		 function );

		return( -1 );
	}
#if PY_MAJOR_VERSION >= 3
	method_name = PyUnicode_FromString(
	               "seek" );
#else
	method_name = PyString_FromString(
	               "seek" );
#endif
#if defined( HAVE_LONG_LONG )
	argument_offset = PyLong_FromLongLong(
	                   (PY_LONG_LONG) offset );
#else
	argument_offset = PyLong_FromLongLong(
	                   (long) offset );
#endif
#if PY_MAJOR_VERSION >= 3
	argument_whence = PyLong_FromLong(
	                   (long) whence );
#else
	argument_whence = PyInt_FromLong(
	                   (long) whence );
#endif
	PyErr_Clear();

	method_result = PyObject_CallMethodObjArgs(
	                 file_object,
	                 method_name,
	                 argument_offset,
	                 argument_whence,
	                 NULL );

	if( PyErr_Occurred() )
	{
		pysmraw_error_fetch(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek in file object.",
		 function );

		goto on_error;
	}
	if( method_result == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: missing method result.",
		 function );

		goto on_error;
	}
	Py_DecRef(
	 method_result );

	Py_DecRef(
	 argument_whence );

	Py_DecRef(
	 argument_offset );

	Py_DecRef(
	 method_name );

	return( 1 );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( argument_whence != NULL )
	{
		Py_DecRef(
		 argument_whence );
	}
	if( argument_offset != NULL )
	{
		Py_DecRef(
		 argument_offset );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
/* Writes a buffer to the file object
 * Make sure to hold the GIL state before calling this function
 * Returns the number of bytes written if successful, or -1 on error
 */
ssize_t pysmraw_file_object_write_buffer(
         PyObject *file_object,
         const uint8_t *buffer,
         size_t size,
         libcerror_error_t **error )
{
	PyObject *argument_string = NULL;
	PyObject *method_name     = NULL;
	PyObject *method_result   = NULL;
	static char *function     = "pysmraw_file_object_write_buffer";

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
	if( buffer == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid buffer.",
		 function );

		return( -1 );
	}
#if SIZEOF_SIZE_T > SIZEOF_INT
	if( size > (size_t) INT_MAX )
#else
	if( size > (size_t) SSIZE_MAX )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( size > 0 )
	{
#if PY_MAJOR_VERSION >= 3
		method_name = PyUnicode_FromString(
			       "write" );
#else
		method_name = PyString_FromString(
			       "write" );
#endif
#if PY_MAJOR_VERSION >= 3
		argument_string = PyBytes_FromStringAndSize(
		                   (char *) buffer,
		                   size );
#else
		argument_string = PyString_FromStringAndSize(
		                   (char *) buffer,
		                   size );
#endif
		PyErr_Clear();

		method_result = PyObject_CallMethodObjArgs(
				 file_object,
				 method_name,
				 argument_string,
				 NULL );

		if( PyErr_Occurred() )
		{
			pysmraw_error_fetch(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_WRITE_FAILED,
			 "%s: unable to write to file object.",
			 function );

			goto on_error;
		}
		if( method_result == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
			 "%s: missing method result.",
			 function );

			goto on_error;
		}
		Py_DecRef(
		 method_result );

		Py_DecRef(
		 argument_string );

		Py_DecRef(
		 method_name );
	}
	return( (ssize_t) size );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( argument_string != NULL )
	{
		Py_DecRef(
		 argument_string );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
/* Reads a buffer from the file object
 * Make sure to hold the GIL state before calling this function
 * Returns the number of bytes read if successful, or -1 on error
 */
ssize_t pysmraw_file_object_read_buffer(
         PyObject *file_object,
         uint8_t *buffer,
         size_t size,
         libcerror_error_t **error )
{
	PyObject *argument_size    = NULL;
	PyObject *method_name      = NULL;
	PyObject *method_result    = NULL;
	static char *function      = "pysmraw_file_object_read_buffer";
	char *safe_buffer          = NULL;
	Py_ssize_t safe_read_count = 0;
	ssize_t read_count         = 0;
	int result                 = 0;

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
	if( buffer == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid buffer.",
		 function );

		return( -1 );
	}
	if( size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( size > 0 )
	{
#if PY_MAJOR_VERSION >= 3
		method_name = PyUnicode_FromString(
			       "read" );
#else
		method_name = PyString_FromString(
			       "read" );
#endif
		argument_size = PyLong_FromSize_t(
				 size );

		PyErr_Clear();

		method_result = PyObject_CallMethodObjArgs(
				 file_object,
				 method_name,
				 argument_size,
				 NULL );

		if( PyErr_Occurred() )
		{
			pysmraw_error_fetch(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read from file object.",
			 function );

			goto on_error;
		}
		if( method_result == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
			 "%s: missing method result.",
			 function );

			goto on_error;
		}
#if PY_MAJOR_VERSION >= 3
		result = PyObject_IsInstance(
		          method_result,
		          (PyObject *) &PyBytes_Type );
#else
		result = PyObject_IsInstance(
		          method_result,
		          (PyObject *) &PyString_Type );
#endif
		if( result == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to determine if method result is a binary string object.",
			 function );

			goto on_error;
		}
		else if( result == 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
			 "%s: invalid method result value is not a binary string object.",
			 function );

			goto on_error;
		}
#if PY_MAJOR_VERSION >= 3
		result = PyBytes_AsStringAndSize(
			  method_result,
			  &safe_buffer,
			  &safe_read_count );
#else
		result = PyString_AsStringAndSize(
			  method_result,
			  &safe_buffer,
			  &safe_read_count );
#endif
		if( result == -1 )
		{
			pysmraw_error_fetch(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read from file object.",
			 function );

			goto on_error;
		}
		if( safe_read_count > (Py_ssize_t) SSIZE_MAX )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
			 "%s: invalid read count value exceeds maximum.",
			 function );

			goto on_error;
		}
		read_count = (ssize_t) safe_read_count;

		if( memory_copy(
		     buffer,
		     safe_buffer,
		     read_count ) == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_MEMORY,
			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
			 "%s: unable to data to buffer.",
			 function );

			goto on_error;
		}
		Py_DecRef(
		 method_result );

		Py_DecRef(
		 argument_size );

		Py_DecRef(
		 method_name );
	}
	return( read_count );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( argument_size != NULL )
	{
		Py_DecRef(
		 argument_size );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
/* Retrieves the size of the file object
 * Make sure to hold the GIL state before calling this function
 * Returns 1 if successful or -1 on error
 */
int pysmraw_file_object_get_size(
     PyObject *file_object,
     size64_t *size,
     libcerror_error_t **error )
{
	PyObject *method_name   = NULL;
	PyObject *method_result = NULL;
	static char *function   = "pysmraw_file_object_get_size";

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
	if( size == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid size.",
		 function );

		return( -1 );
	}
#if PY_MAJOR_VERSION >= 3
	method_name = PyUnicode_FromString(
	               "get_size" );
#else
	method_name = PyString_FromString(
	               "get_size" );
#endif
	PyErr_Clear();

	method_result = PyObject_CallMethodObjArgs(
	                 file_object,
	                 method_name,
	                 NULL );

	if( PyErr_Occurred() )
	{
		pysmraw_error_fetch(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve size of file object.",
		 function );

		goto on_error;
	}
	if( method_result == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: missing method result.",
		 function );

		goto on_error;
	}
	if( pysmraw_integer_unsigned_copy_to_64bit(
	     method_result,
	     size,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to convert method result into size of file object.",
		 function );

		goto on_error;
	}
	Py_DecRef(
	 method_result );

	Py_DecRef(
	 method_name );

	return( 1 );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
/* Retrieves the current offset within the file object
 * Make sure to hold the GIL state before calling this function
 * Returns 1 if successful or -1 on error
 */
int pysmraw_file_object_get_offset(
     PyObject *file_object,
     off64_t *offset,
     libcerror_error_t **error )
{
	PyObject *method_name   = NULL;
	PyObject *method_result = NULL;
	static char *function   = "pysmraw_file_object_get_offset";
	int result              = 0;

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
	if( offset == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid offset.",
		 function );

		return( -1 );
	}
#if PY_MAJOR_VERSION >= 3
	method_name = PyUnicode_FromString(
	               "get_offset" );
#else
	method_name = PyString_FromString(
	               "get_offset" );
#endif
	PyErr_Clear();

	/* Determine if the file object has the get_offset method
	 */
	result = PyObject_HasAttr(
	          file_object,
	          method_name );

	if( result == 0 )
	{
		Py_DecRef(
		 method_name );

		/* Fall back to the tell method
		 */
#if PY_MAJOR_VERSION >= 3
		method_name = PyUnicode_FromString(
		               "tell" );
#else
		method_name = PyString_FromString(
		               "tell" );
#endif
	}
	PyErr_Clear();

	method_result = PyObject_CallMethodObjArgs(
	                 file_object,
	                 method_name,
	                 NULL );

	if( PyErr_Occurred() )
	{
		pysmraw_error_fetch(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve current offset in file object.",
		 function );

		goto on_error;
	}
	if( method_result == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: missing method result.",
		 function );

		goto on_error;
	}
	if( pysmraw_integer_signed_copy_to_64bit(
	     method_result,
	     offset,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to convert method result into current offset of file object.",
		 function );

		goto on_error;
	}
	Py_DecRef(
	 method_result );

	Py_DecRef(
	 method_name );

	return( 1 );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
Esempio n. 6
0
/* Copies a Python int or long object to an unsigned 64-bit value
 * Returns 1 if successful or -1 on error
 */
int pysmraw_integer_unsigned_copy_to_64bit(
     PyObject *integer_object,
     uint64_t *value_64bit,
     libcerror_error_t **error )
{
	static char *function   = "pysmraw_integer_unsigned_copy_to_64bit";
	int result              = 0;

#if defined( HAVE_LONG_LONG )
	PY_LONG_LONG long_value = 0;
#else
	long long_value         = 0;
#endif

	if( integer_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid integer object.",
		 function );

		return( -1 );
	}
	PyErr_Clear();

	result = PyObject_IsInstance(
	          integer_object,
	          (PyObject *) &PyLong_Type );

	if( result == -1 )
	{
		pysmraw_error_fetch(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to determine if integer object is of type long.",
		 function );

		return( -1 );
	}
	else if( result != 0 )
	{
		PyErr_Clear();

#if defined( HAVE_LONG_LONG )
		long_value = PyLong_AsUnsignedLongLong(
		              integer_object );
#else
		long_value = PyLong_AsUnsignedLong(
		              integer_object );
#endif
	}
#if PY_MAJOR_VERSION < 3
	if( result == 0 )
	{
		PyErr_Clear();

		result = PyObject_IsInstance(
		          integer_object,
		          (PyObject *) &PyInt_Type );

		if( result == -1 )
		{
			pysmraw_error_fetch(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to determine if integer object is of type int.",
			 function );

			return( -1 );
		}
		else if( result != 0 )
		{
			PyErr_Clear();

#if defined( HAVE_LONG_LONG )
			long_value = PyInt_AsUnsignedLongLongMask(
				      integer_object );
#else
			long_value = PyInt_AsUnsignedLongMask(
				      integer_object );
#endif
		}
	}
#endif /* PY_MAJOR_VERSION < 3 */
	if( result == 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unsupported integer object type.",
		 function );

		return( -1 );
	}
	if( PyErr_Occurred() )
	{
		pysmraw_error_fetch(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to convert integer object to long.",
		 function );

		return( -1 );
	}
#if defined( HAVE_LONG_LONG )
#if ( SIZEOF_LONG_LONG > 8 )
	if( ( long_value < (PY_LONG_LONG) 0 )
	 || ( long_value > (PY_LONG_LONG) UINT64_MAX ) )
#else
	if( long_value < (PY_LONG_LONG) 0 )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid long value out of bounds.",
		 function );

		return( -1 );
	}
#else
#if ( SIZEOF_LONG > 8 )
	if( ( long_value < (long) 0 )
	 || ( long_value > (long) UINT64_MAX ) )
#else
	if( long_value < (PY_LONG_LONG) 0 )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid long value out of bounds.",
		 function );

		return( -1 );
	}
#endif
	*value_64bit = (uint64_t) long_value;

	return( 1 );
}