pk.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 675 行 · 第 1/2 页
C
675 行
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
pk.c
Abstract:
Revision History
--*/
/* This file implements parsing and reading of uncompressed
PKWARE archive format files */
#include <efi.h>
#include <efidriverlib.h>
//#include <stdio.h>
//#include <sys/stat.h>
//#include <time.h>
#include "isltype.h"
#include "isl_internal.h"
//#include "pkapi.h"
//pause(char*);
static void
CRC32_Init(
uint32 table[256]);
static uint32
CRC32(
uint32 table[256],
ISL_CONST_DATA_PTR pData);
static ISL_STATUS
ParseLocalFile(
PK_LOCAL_FILE_PTR pLocal,
ISL_CONST_DATA Input,
ISL_CONST_DATA_PTR UpdatedInput);
static ISL_STATUS
ParseCentralFile(
PK_CENTRAL_FILE_PTR CentralPtr,
ISL_CONST_DATA Input,
ISL_CONST_DATA_PTR UpdatedInput);
static ISL_STATUS
ParseCentralDirEnd(
ISL_MEMORY_CONTEXT_PTR pMem,
ISL_CONST_DATA Input,
ISL_CONST_DATA_PTR UpdatedInput,
PK_ARCHIVE_PTR pArchive);
/*-----------------------------------------------------------------------------
* Name: pk_InitializeFromMemory
*
* Description:
*
* Parameters:
* MemPtr (input)
* Fileimage (input)
*
* Return value:
*
* Error Codes:
*---------------------------------------------------------------------------*/
PK_ARCHIVE_PTR
pk_InitializeFromMemory(
ISL_MEMORY_CONTEXT_PTR MemPtr,
ISL_CONST_DATA Fileimage )
{
PK_ARCHIVE_PTR pkArchivePtr = NULL;
ISL_CONST_DATA UpdatedInput;
ISL_CONST_DATA Input;
uint32 localFileSig= LOCAL_FILE_HEADER_SIGNATURE;
uint32 centralFileSig= CENTRAL_FILE_HEADER_SIGNATURE;
uint32 endCenDirSig= END_OF_CENTRAL_DIR_SIGNATURE;
uint8* pos = NULL;
UpdatedInput.Length = 0;
pkArchivePtr = isl_AllocateMemory(MemPtr, sizeof(PK_ARCHIVE));
if (pkArchivePtr == NULL) {
return NULL;
}
pkArchivePtr->pMem = MemPtr;
pkArchivePtr->Archive = Fileimage;
/* Start parsing */
Input = Fileimage;
pos = (uint8*)Fileimage.Data;
/* We look for all of the local files first */
while ( Input.Length > 4
&& ( 0 == EfiCompareMem( &localFileSig, (void*)Input.Data, sizeof(uint32) ) )
)
{
PK_LOCAL_FILE_PTR LocalPtr;
LocalPtr = isl_AllocateMemory(MemPtr, sizeof(PK_LOCAL_FILE));
if (LocalPtr == NULL ||
ISL_OK != ParseLocalFile(LocalPtr, Input, &UpdatedInput))
{
goto RECYCLE_AND_FAIL;
}
LocalPtr->Next = pkArchivePtr->LocalFiles;
pkArchivePtr->LocalFiles = LocalPtr;
Input = UpdatedInput;
}
/* Now we look for all of the central files */
while (Input.Length > 4
&& ( 0 == EfiCompareMem( ¢ralFileSig, (void*)Input.Data, sizeof(uint32) ) )
)
{
PK_CENTRAL_FILE_PTR CentralPtr;
CentralPtr = isl_AllocateMemory(MemPtr, sizeof(PK_CENTRAL_FILE));
if (CentralPtr == NULL ||
ISL_OK != ParseCentralFile(CentralPtr, Input, &UpdatedInput)) {
goto RECYCLE_AND_FAIL;
}
CentralPtr->Next = pkArchivePtr->CentralFiles;
pkArchivePtr->CentralFiles = CentralPtr;
Input = UpdatedInput;
}
/* Finally, parse the end of the Central Directory */
while (Input.Length > 4
&& ( 0 == EfiCompareMem( &endCenDirSig, (void*)Input.Data, sizeof(uint32) ) )
)
{
if (ISL_OK != ParseCentralDirEnd(
MemPtr,
Input,
&UpdatedInput,
pkArchivePtr))
goto RECYCLE_AND_FAIL;
Input = UpdatedInput;
}
/* Check to see if file was fully parsed */
if (UpdatedInput.Length != 0) goto RECYCLE_AND_FAIL;
return pkArchivePtr;
RECYCLE_AND_FAIL:
(void)pk_RecycleArchive(pkArchivePtr);
return NULL;
}
/*-----------------------------------------------------------------------------
* Name: CRC32_Init
*
* Description:
*
* Parameters:
*
* Return value:
*
* Error Codes:
*---------------------------------------------------------------------------*/
static void
CRC32_Init(
uint32 table[256])
{
uint32 i, j, pos, num;
/* First, we need to initialize the CRC table, using the seed specified
by the PKWARE specification */
num = 0xEDB88320L;
for (i = 0; i < 256; i++)
{
pos = i;
for (j = 8; j > 0; j--)
{
if (pos & 1)
pos = (pos >> 1) ^ num;
else
pos >>= 1;
}
table[i] = pos;
}
}
/*-----------------------------------------------------------------------------
* Name: CRC32
*
* Description:
*
* Parameters:
*
* Return value:
*
* Error Codes:
*---------------------------------------------------------------------------*/
static uint32
CRC32(
uint32 table[256],
ISL_CONST_DATA_PTR pData)
{
uint32 newCRC, i;
const uint8 *data;
if (!pData || !pData->Length)
return 0;
/* Now, we can get to the business of calculating the CRC */
newCRC = 0xFFFFFFFF;
data = pData->Data;
for (i=0; i<pData->Length; i++)
{
newCRC = ((newCRC>>8) & 0x00FFFFFF) ^ table[ (newCRC^data[i]) & 0xFF ];
}
return( newCRC^0xFFFFFFFF );
}
/*-----------------------------------------------------------------------------
* Name: pk_RecycleArchive
*
* Description:
*
* Parameters:
*
* Return value:
*
* Error Codes:
*---------------------------------------------------------------------------*/
ISL_STATUS
pk_RecycleArchive(
PK_ARCHIVE_PTR pArchive )
{
PK_LOCAL_FILE_PTR pLocal = NULL;
PK_CENTRAL_FILE_PTR pCentral = NULL;
if (!pArchive)
return ISL_OK;
/* Free local file structures */
while (pArchive->LocalFiles)
{
pLocal = pArchive->LocalFiles;
pArchive->LocalFiles = pArchive->LocalFiles->Next;
isl_FreeMemory(pArchive->pMem, pLocal);
}
/* Free central file structures */
while (pArchive->CentralFiles)
{
pCentral = pArchive->CentralFiles;
pArchive->CentralFiles = pArchive->CentralFiles->Next;
isl_FreeMemory(pArchive->pMem, pCentral);
}
/* Free central directory end */
if (pArchive->DirEnd)
{
isl_FreeMemory(pArchive->pMem, pArchive->DirEnd);
}
/* Free the archive itself */
isl_FreeMemory(pArchive->pMem, pArchive);
return ISL_OK;
}
/*-----------------------------------------------------------------------------
* Name: pk_FindFile
*
* Description:
*
* Parameters:
*
* Return value:
*
* Error Codes:
*---------------------------------------------------------------------------*/
ISL_STATUS
pk_FindFile(
PK_ARCHIVE_PTR pArchive,
ISL_CONST_DATA Filename,
ISL_CONST_DATA_PTR Filedata )
{
PK_LOCAL_FILE_PTR pLocal = NULL;
if (pArchive == NULL ||
Filename.Length == 0 ||
Filedata == NULL )
{
return ISL_FAIL;
}
pLocal = pArchive->LocalFiles;
while (pLocal)
{
if (pLocal->Filename.Length == Filename.Length)
{
if (0 == cssm_memcmp(
pLocal->Filename.Data,
Filename.Data,
Filename.Length))
{
*Filedata = pLocal->Filedata;
return ISL_OK;
}
}
pLocal = pLocal->Next;
}
return ISL_FAIL;
}
/*-----------------------------------------------------------------------------
* Name: pk_CreateFileEnumerator
*
* Description:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?