pk.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 675 行 · 第 1/2 页

C
675
字号
 *
 * Parameters: 
 *
 * Return value:
 * 
 * Error Codes:
 *---------------------------------------------------------------------------*/
PK_ITERATOR_PTR
pk_CreateFileEnumerator(
	PK_ARCHIVE_PTR PKArchivePtr)
{
	PK_ITERATOR_PTR	toReturn;

	if (PKArchivePtr == NULL)
		return NULL;

	/* RLM: 4/14/98: why are we calling cssm_malloc() instead of the local
	 * memory allocation routines.
	 */
	toReturn = isl_AllocateMemory(PKArchivePtr->pMem, sizeof(PK_ITERATOR));
	if (toReturn == NULL) return NULL;

	toReturn->LocalFilePtr = PKArchivePtr->LocalFiles;
	toReturn->PKArchivePtr = PKArchivePtr;
	return toReturn;
}

/*-----------------------------------------------------------------------------
 * Name: pk_GetNextFile
 *
 * Description:
 *
 * Parameters: 
 *
 * Return value:
 * 
 * Error Codes:
 *---------------------------------------------------------------------------*/
ISL_STATUS
pk_GetNextFile(
	PK_ITERATOR_PTR		PKIteratorPtr,
	ISL_CONST_DATA_PTR	FilenamePtr,
	ISL_CONST_DATA_PTR	FiledataPtr)
{
	if (PKIteratorPtr == NULL || 
		FilenamePtr == NULL || 
		FiledataPtr == NULL || 
		PKIteratorPtr->LocalFilePtr == NULL)
		return ISL_FAIL;

	/* RLM: 4/14/98: we're doing shallow copies here...is that okay? */
	*FilenamePtr = PKIteratorPtr->LocalFilePtr->Filename;
	*FiledataPtr = PKIteratorPtr->LocalFilePtr->Filedata;
	PKIteratorPtr->LocalFilePtr = PKIteratorPtr->LocalFilePtr->Next;

	return ISL_OK;
}

/*-----------------------------------------------------------------------------
 * Name: pk_RecycleFileEnumerator
 *
 * Description:
 *
 * Parameters: 
 *
 * Return value:
 * 
 * Error Codes:
 *---------------------------------------------------------------------------*/
ISL_STATUS
pk_RecycleFileEnumerator(
	PK_ITERATOR_PTR		pIterator )
{
	if (pIterator)
		isl_FreeMemory(pIterator->PKArchivePtr->pMem, pIterator);
	return ISL_OK;
}

/*-----------------------------------------------------------------------------
 * Name: ParseLocalFile
 *
 * Description:
 *
 * Parameters: 
 *
 * Return value:
 * 
 * Error Codes:
 *---------------------------------------------------------------------------*/
static ISL_STATUS
ParseLocalFile(
	PK_LOCAL_FILE_PTR pLocal,
    ISL_CONST_DATA Input,
    ISL_CONST_DATA_PTR UpdatedInput)
{
    const uint8 * pos;
    uint32 length;
	uint32 crc;
	uint32 table[256];


	if (pLocal == NULL ||
        Input.Data == NULL ||
        Input.Length == 0)
		return ISL_FAIL;


	/* Initialize local variables */
	CRC32_Init(table);
    pos = Input.Data;
    length = Input.Length;

	/* Skip over signature */
    if (4 > length) return ISL_FAIL;

	pos += 4;
    length -= 4;

	/* Allocate the data structure and patch the linked list */

	/* RLM: 4/14/98: we've added pLocal to the linked list, but don't
	 * restore the list to its original state (and free up pLocal) if
	 * we fail after this point.  Is that okay?
	 */

	/* RLM: 4/14/98: more memory sharing in the next line...OK? */
    if (sizeof(PK_LOCAL_FILE_HEADER) > length) return ISL_FAIL;

	pLocal->Header = (PK_LOCAL_FILE_HEADER_PTR)pos;
	pos += sizeof(PK_LOCAL_FILE_HEADER);
    length -= sizeof(PK_LOCAL_FILE_HEADER);

	/* Set up pointers to filename, extra field, and file data */
	pLocal->Filename.Length = pLocal->Header->FilenameLength;
	pLocal->ExtraField.Length = pLocal->Header->ExtraFieldLength;
	pLocal->Filedata.Length = pLocal->Header->CompressedSize;

	/* RLM: 4/14/98: We're sharing a lot of memory in the code below.
	 * are we sure no-one is going to free up (*pos)?
	 */
    if (pLocal->Filename.Length > length) return ISL_FAIL;
	pLocal->Filename.Data = pos;
	pos += pLocal->Filename.Length;
    length -= pLocal->Filename.Length;

    if (pLocal->ExtraField.Length > length) return ISL_FAIL;
	pLocal->ExtraField.Data = pos;
	pos += pLocal->ExtraField.Length;
    length -= pLocal->ExtraField.Length;

	if (pLocal->Filedata.Length > length) return ISL_FAIL;
    pLocal->Filedata.Data = pos;
	pos += pLocal->Filedata.Length;
    length -= pLocal->Filedata.Length;

	/* Check CRC */
	crc = CRC32(table, &pLocal->Filedata);
	if (crc != pLocal->Header->crc32) return ISL_FAIL;


	/* If bit 3 of general purpose bit flag is set, then there is
	   another descriptor struct to worry about */
	if (pLocal->Header->GeneralPurposeBitFlag & 0x00001000)
	{
	  /* RLM: 4/14/98: Yet more memory sharing.  OK? */
        if (sizeof(ISL_DATA_DESCRIPTOR) > length) return ISL_FAIL;
        
		pLocal->DataDescriptor = (ISL_DATA_DESCRIPTOR_PTR)pos;
		pos += sizeof(ISL_DATA_DESCRIPTOR);
        length -= sizeof(ISL_DATA_DESCRIPTOR);
	
		/* Make sure this archive is uncompressed */
		if (pLocal->DataDescriptor->CompressedSize !=
			pLocal->DataDescriptor->UncompressedSize)
		{	
			return ISL_FAIL;
		}
	} 
	else {
		
		/* Make sure this archive is uncompressed */
		if (pLocal->Header->CompressedSize !=
			pLocal->Header->UncompressedSize)
		{
			return ISL_FAIL;
		}
	}

	
    if (UpdatedInput)
    {
        UpdatedInput->Data = pos;
        UpdatedInput->Length = length;
    }

	return ISL_OK;
}

/*-----------------------------------------------------------------------------
 * Name: ParseCentralFile
 *
 * Description:
 *
 * Parameters: 
 *
 * Return value:
 * 
 * Error Codes:
 *---------------------------------------------------------------------------*/
static ISL_STATUS
ParseCentralFile(
	PK_CENTRAL_FILE_PTR	pCentral,
	ISL_CONST_DATA Input,
    ISL_CONST_DATA_PTR UpdatedInput)
{
    const uint8* pos;
    uint32 length;

	if (pCentral == NULL ||
        Input.Data == NULL ||
        Input.Length == 0)
		return ISL_FAIL;

    /* Initialize Local Variables */
    pos = Input.Data;
    length = Input.Length;
	/* Skip over the signature */
    if (4 > length) return ISL_FAIL;
	pos += 4;
    length -= 4;

	/* Grab the header */
	/* RLM: 4/14/98: memory-sharing...OK? */
    if (sizeof(PK_CENTRAL_FILE_HEADER) > length) return ISL_FAIL;
	pCentral->Header = (PK_CENTRAL_FILE_HEADER_PTR)pos;
	pos += sizeof(PK_CENTRAL_FILE_HEADER);
    length -= sizeof(PK_CENTRAL_FILE_HEADER);

	/* Check to make sure the data is not compressed */
	if (pCentral->Header->CompressedSize !=
		pCentral->Header->UncompressedSize)
		return ISL_FAIL;

	/* Set pointers to filename, extra field, and file comment */
	pCentral->Filename.Length = pCentral->Header->FilenameLength;
	pCentral->ExtraField.Length = pCentral->Header->ExtraFieldLength;
	pCentral->FileComment.Length = pCentral->Header->FileCommentLength;
	/* RLM: 4/14/98: memory sharing...OK? */
    if (pCentral->Filename.Length > length) return ISL_FAIL;
	pCentral->Filename.Data = pos;
	pos += pCentral->Filename.Length;
    length -= pCentral->Filename.Length;

	/* RLM: 4/14/98: memory sharing...OK? */
    if (pCentral->ExtraField.Length > length) return ISL_FAIL;
	pCentral->ExtraField.Data = pos;
	pos += pCentral->ExtraField.Length;
    length -= pCentral->ExtraField.Length;

	/* RLM: 4/14/98: memory sharing...OK? */
    if (pCentral->FileComment.Length > length) return ISL_FAIL;
	pCentral->FileComment.Data = pos;
	pos += pCentral->FileComment.Length;
    length -= pCentral->FileComment.Length;

    if (UpdatedInput)
    {
        UpdatedInput->Data = pos;
        UpdatedInput->Length = length;
    }
	return ISL_OK;
}

/*-----------------------------------------------------------------------------
 * Name: ParseCentralDirEnd
 *
 * Description:
 *
 * Parameters: 
 *
 * Return value:
 * 
 * Error Codes:
 *---------------------------------------------------------------------------*/
static ISL_STATUS
ParseCentralDirEnd(
	ISL_MEMORY_CONTEXT_PTR	pMem,
	ISL_CONST_DATA Input,
    ISL_CONST_DATA_PTR UpdatedInput,
	PK_ARCHIVE_PTR	pArchive)
{
    const uint8 * pos;
    uint32 length;
	PK_CENTRAL_DIR_END_PTR pEnd = NULL;

	if (pArchive == NULL ||
        Input.Data == NULL ||
        Input.Length == 0)
		return ISL_FAIL;

    /* Initialize Local Variables */
    pos = Input.Data;
    length = Input.Length;
	/* Skip over signature */
    if (4 > length) return ISL_FAIL;
	pos += 4;
    length -= 4;

	pEnd = isl_AllocateMemory(pMem, sizeof(PK_CENTRAL_DIR_END));
	if (!pEnd) {
		return ISL_FAIL;
	}
	pArchive->DirEnd = pEnd;

	/* RLM: 4/14/98: memory sharing...OK? */
    if (sizeof(PK_CENTRAL_DIR_END_HEADER) > length) return ISL_FAIL;
	pEnd->Header = (PK_CENTRAL_DIR_END_HEADER_PTR)pos;
	pos += sizeof(PK_CENTRAL_DIR_END_HEADER);
    length -= sizeof(PK_CENTRAL_DIR_END_HEADER);

	/* Set up the zip file comment field */
	pEnd->ZipFileComment.Length = pEnd->Header->ZipfileCommentLength;
	/* RLM: 4/14/98: memory sharing...OK? */
    if (pEnd->ZipFileComment.Length > length) return ISL_FAIL;
	pEnd->ZipFileComment.Data = pos;
	pos += pEnd->ZipFileComment.Length;
    length -= pEnd->ZipFileComment.Length;

    if (UpdatedInput)
    {
        UpdatedInput->Data = pos;
        UpdatedInput->Length = length;
    }
	return ISL_OK;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?