📄 pak.c
字号:
/*************************************************************************** * pak.c * * Fri Sep 23 08:57:35 2005 * Copyright 2005 Alpher * Email: alpher_zmx@yahoo.com.cn ****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "pak.h"gboolean GenerateHFT(){ /* Declare local variables */ gint iRandom = 0; /* Recieves a random number */ guint32 dwFileCount = 0; /* Number of files in compile directory */ DIR *dp; struct dirent *entry; struct stat statbuf; gint i; gchar Buffer[300] = {0};/* All purpose buffer */ /* Seed the timer with the clock */ srand( (unsigned)time(NULL) ); /* Create the header signature */ memcpy( m_Header.szSignature, "LLKPAK", 6 ); /* Set the file version */ m_Header.fVersion = 2.5; /* Get a random 1 or 0 (TRUE or FALSE) and set cypher direction */ iRandom = rand()%2; m_Header.bCypherAddition = (gboolean)iRandom; /* Get the caesar cypher value */ iRandom = rand()%256; m_Header.iCypherValue = (guint8)iRandom; /* Create a unique ID */ for( i = 0; i < 10; i++ ) { iRandom = rand()%256; m_Header.szUniqueID[i] = (gchar)iRandom; } /* Get a local copy of the compilation folder name so that the one in the class isn't altered */ if( strlen(m_szFolderPath) == 0 ){ return FALSE; } memcpy( Buffer, m_szFolderPath, 300 ); if( (dp = opendir(Buffer)) == NULL ) { /* can not open directory */ return FALSE; } chdir(Buffer); /* Start filling in the file table */ while( (entry = readdir(dp)) != NULL ) { lstat(entry->d_name,&statbuf); if( S_ISDIR(statbuf.st_mode) ) { if( strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0 ) continue; else {/* ignore directory */ continue; } } else { /* Create a node entry for the file table */ struct sFileTableEntry * TempEntry = (struct sFileTableEntry *)g_malloc(sizeof(struct sFileTableEntry)); /* Store the file name */ memcpy( TempEntry->szFileName, entry->d_name, 30 ); /* Store the file size */ TempEntry->dwFileSize = (guint32)statbuf.st_size; /* Default the offset value (worked out later) */ TempEntry->dwOffset = 0; /* Add this to the file table,add to the front */ TempEntry->Next = m_FileTable; m_FileTable = TempEntry; /* Increment the files counter */ dwFileCount++; } } chdir(".."); /* Close the search handle */ closedir(dp); /* Mark the number of files added in the header */ m_Header.dwNumFTEntries = dwFileCount; return TRUE;}gboolean WorkOutOffsets(){ /* Declare local variables */ guint32 dwFileHFTData = 0; /* Size of header and file table */ guint32 dwOffset = 0; /* Individual files offset in to the PAK */ struct sFileTableEntry* Current; /* Work out the size, in bytes, of the header and FT */ dwFileHFTData = sizeof(struct sPakHeader) + (m_Header.dwNumFTEntries * sizeof(struct sFileTableEntry)); /* Create a temporary node and make it the head of the linked list */ Current = m_FileTable; /* Get the first offset */ dwOffset = dwFileHFTData + 1; while( Current != NULL ) { /* Set the offset */ Current->dwOffset = dwOffset; /* Update the offset */ dwOffset = dwOffset + Current->dwFileSize; /* Update the current variable */ Current = Current->Next; } return TRUE;}gboolean CreatePak( gchar* Path, gchar* Output ){ /* Declare local variables */ FILE* PAKStream; /* File pointer for writing to the PAK */ FILE* InputStream; /* For reading in each file to be added */ fpos_t Pos; /* Position in the PAK file,fpos_t,defined in stdio.h */ gchar Buffer[300] = {0};/* General purpose buffer */ gint iStringLength = 0;/* String length */ struct sFileTableEntry* Current; memset( &m_Header, 0 ,sizeof(struct sPakHeader) ); memset( m_szFolderPath, 0 ,300); memset( m_szPakName, 0 , 300); m_FileTable = NULL; /* Error check */ if( (Path == NULL) || (Output == NULL) ){ return FALSE; } /* Store the function paramaters in the class */ iStringLength = strlen( Path ); memcpy( m_szFolderPath, Path, iStringLength ); iStringLength = strlen( Output ); memcpy( m_szPakName, Output, iStringLength ); /* Create the header and file table */ if( !GenerateHFT() ){g_print("%s\n",_("GenerateHFT() failed.")); return FALSE; } /* Work out the offsets */ if( !WorkOutOffsets() ){g_print("%s\n",_("WorkOutOffsets() failed.")); return FALSE; } /* Open the file stream for writing the PAK */ PAKStream = fopen( Output, "wb" ); if( !PAKStream ){ return FALSE; } /* Write the PAK header */ fwrite( &m_Header, sizeof(struct sPakHeader), 1, PAKStream ); /* Get a local copy of the file table head */ Current = m_FileTable; /* Encrypt and write out each file table entry */ while( Current != NULL ) { /* Create a BYTE pointer for byte access to a file table entry */ guint8 * Ptr = NULL; gint i; /* Create a BYTE array the same size as a file table entry */ Ptr = (guint8 *)g_malloc(sizeof(struct sFileTableEntry)); /* Copy the current file table entry in to the byte array */ memcpy( Ptr, Current, sizeof(struct sFileTableEntry) ); for( i = 0; i < sizeof(struct sFileTableEntry); i++ ) { /* Temporary BYTE variable */ guint8 Temp = 0; /* Make equal to the relevant byte of the FT entry */ Temp = Ptr[i]; /* Encrypt BYTE according to the caesar cypher */ if( m_Header.bCypherAddition == TRUE ) Temp += m_Header.iCypherValue; else Temp -= m_Header.iCypherValue; /* Write the FT encrypted BYTE value */ fwrite( &Temp, sizeof(guint8), 1, PAKStream ); } /* Move on to the next file table entry */ Current = Current->Next; /* Delete the temporary BYTE pointer */ g_free(Ptr); } /* Close the stream used for the header and file table */ fclose( PAKStream ); /* Reset variable to be the head of the file table */ Current = m_FileTable; /* Read in each file at a time, encrypt it using the cypher and add to PAK */ while( Current != NULL ) { /* Declare local variables */ guint8 DataBuffer = 0; guint32 i; /* Open the PAK file for writing g_print("%s\n%s\n",m_szFolderPath,m_szPakName);*/ PAKStream = fopen( Output, "r+b" ); if( !PAKStream ){ return FALSE; } /* Create the absolute path of the file to be added to the PAK */ memcpy( Buffer, m_szFolderPath, 300 ); strcat( Buffer, "/"); /* if in windows system,this should be strcat(Buffer,"\\"); */ strcat( Buffer, Current->szFileName ); /* Open the data stream for reading in a file to be added to the PAK */ InputStream = fopen( Buffer, "rb" ); if( !InputStream ) { fclose( PAKStream ); return FALSE; } /* Set the position in the PAK file for this file to be written at */ /* If not GNU system,this should be Pos = Current->dwOffset */#ifdef WIN32 Pos = Current->dwOffset;#else Pos.__pos = Current->dwOffset; #endif fsetpos( PAKStream, &Pos ); /* Read in the file a byte at a time, encrypt it and write to PAK */ for( i = 0; i < Current->dwFileSize; i++ ) { /* Get the first BYTE from the file to be added */ DataBuffer = fgetc( InputStream ); /* Encrypt the file accordingly */ if( m_Header.bCypherAddition == TRUE ) DataBuffer += m_Header.iCypherValue; else DataBuffer -= m_Header.iCypherValue; /* Write to the PAK file starting at the offset */ fwrite( &DataBuffer, sizeof(guint8), 1, PAKStream );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -