/** @file Efi Compressor Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include /* UefiDecompress(data_buffer, size, original_size) */ STATIC PyObject* UefiDecompress( PyObject *Self, PyObject *Args ) { PyObject *SrcData; UINT32 SrcDataSize; UINT32 DstDataSize; UINTN Status; UINT8 *SrcBuf; UINT8 *DstBuf; UINT8 *TmpBuf; Py_ssize_t SegNum; Py_ssize_t Index; Status = PyArg_ParseTuple( Args, "Oi", &SrcData, &SrcDataSize ); if (Status == 0) { return NULL; } if (SrcData->ob_type->tp_as_buffer == NULL || SrcData->ob_type->tp_as_buffer->bf_getreadbuffer == NULL || SrcData->ob_type->tp_as_buffer->bf_getsegcount == NULL) { PyErr_SetString(PyExc_Exception, "First argument is not a buffer\n"); return NULL; } // Because some Python objects which support "buffer" protocol have more than one // memory segment, we have to copy them into a contiguous memory. SrcBuf = PyMem_Malloc(SrcDataSize); if (SrcBuf == NULL) { PyErr_SetString(PyExc_Exception, "Not enough memory\n"); goto ERROR; } SegNum = SrcData->ob_type->tp_as_buffer->bf_getsegcount((PyObject *)SrcData, NULL); TmpBuf = SrcBuf; for (Index = 0; Index < SegNum; ++Index) { VOID *BufSeg; Py_ssize_t Len; Len = SrcData->ob_type->tp_as_buffer->bf_getreadbuffer((PyObject *)SrcData, Index, &BufSeg); if (Len < 0) { PyErr_SetString(PyExc_Exception, "Buffer segment is not available\n"); goto ERROR; } memcpy(TmpBuf, BufSeg, Len); TmpBuf += Len; } Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID **)&DstBuf, &DstDataSize, 1); if (Status != EFI_SUCCESS) { PyErr_SetString(PyExc_Exception, "Failed to decompress\n"); goto ERROR; } return PyBuffer_FromMemory(DstBuf, (Py_ssize_t)DstDataSize); ERROR: if (SrcBuf != NULL) { free(SrcBuf); } if (DstBuf != NULL) { free(DstBuf); } return NULL; } STATIC PyObject* FrameworkDecompress( PyObject *Self, PyObject *Args ) { PyObject *SrcData; UINT32 SrcDataSize; UINT32 DstDataSize; UINTN Status; UINT8 *SrcBuf; UINT8 *DstBuf; UINT8 *TmpBuf; Py_ssize_t SegNum; Py_ssize_t Index; Status = PyArg_ParseTuple( Args, "Oi", &SrcData, &SrcDataSize ); if (Status == 0) { return NULL; } if (SrcData->ob_type->tp_as_buffer == NULL || SrcData->ob_type->tp_as_buffer->bf_getreadbuffer == NULL || SrcData->ob_type->tp_as_buffer->bf_getsegcount == NULL) { PyErr_SetString(PyExc_Exception, "First argument is not a buffer\n"); return NULL; } // Because some Python objects which support "buffer" protocol have more than one // memory segment, we have to copy them into a contiguous memory. SrcBuf = PyMem_Malloc(SrcDataSize); if (SrcBuf == NULL) { PyErr_SetString(PyExc_Exception, "Not enough memory\n"); goto ERROR; } SegNum = SrcData->ob_type->tp_as_buffer->bf_getsegcount((PyObject *)SrcData, NULL); TmpBuf = SrcBuf; for (Index = 0; Index < SegNum; ++Index) { VOID *BufSeg; Py_ssize_t Len; Len = SrcData->ob_type->tp_as_buffer->bf_getreadbuffer((PyObject *)SrcData, Index, &BufSeg); if (Len < 0) { PyErr_SetString(PyExc_Exception, "Buffer segment is not available\n"); goto ERROR; } memcpy(TmpBuf, BufSeg, Len); TmpBuf += Len; } Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID **)&DstBuf, &DstDataSize, 2); if (Status != EFI_SUCCESS) { PyErr_SetString(PyExc_Exception, "Failed to decompress\n"); goto ERROR; } return PyString_FromStringAndSize((CONST INT8*)DstBuf, (Py_ssize_t)DstDataSize); ERROR: if (SrcBuf != NULL) { free(SrcBuf); } if (DstBuf != NULL) { free(DstBuf); } return NULL; } STATIC PyObject* UefiCompress( PyObject *Self, PyObject *Args ) { return NULL; } STATIC PyObject* FrameworkCompress( PyObject *Self, PyObject *Args ) { return NULL; } STATIC INT8 DecompressDocs[] = "Decompress(): Decompress data using UEFI standard algorithm\n"; STATIC INT8 CompressDocs[] = "Compress(): Compress data using UEFI standard algorithm\n"; STATIC PyMethodDef EfiCompressor_Funcs[] = { {"UefiDecompress", (PyCFunction)UefiDecompress, METH_VARARGS, DecompressDocs}, {"UefiCompress", (PyCFunction)UefiCompress, METH_VARARGS, DecompressDocs}, {"FrameworkDecompress", (PyCFunction)FrameworkDecompress, METH_VARARGS, DecompressDocs}, {"FrameworkCompress", (PyCFunction)FrameworkCompress, METH_VARARGS, DecompressDocs}, {NULL, NULL, 0, NULL} }; PyMODINIT_FUNC initEfiCompressor(VOID) { Py_InitModule3("EfiCompressor", EfiCompressor_Funcs, "EFI Compression Algorithm Extension Module"); }