📄 file.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include "file.h"
#include "compress.h"
/*****************************************************************************
File()
in:
none
out:
none
desc:
initializes the class variables
******************************************************************************/
File::File(const string &file){
m_name = file;
m_build_path = "";
m_release_path = "";
m_load_offset = 0;
m_name_offset = 0;
// m_memory_section = ?;
m_file_attributes = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_COMPRESSED;
m_flags = 0;
m_file_size = 0;
set_file();
memset(&m_file_time, 0, sizeof(m_file_time));
}
/*****************************************************************************
convert_file_attributes_to_flags()
in:
string token - token to set flags for
out:
none
desc:
this function is needed because CE decided to reuse several bits and
therefor not all the flags match up with the NT defined defaults.
NOTE: this is overridden in the module class
******************************************************************************/
void File::convert_file_attributes_to_flags(string token, CompressorList &compressor_list){
token = lowercase(token);
if(is_module()){
// for files that will be modules
m_file_attributes &= ~FILE_ATTRIBUTE_COMPRESSED;
m_flags |= FLAG_SPLIT_CODE;
if(token.find('p') != string::npos) m_flags |= FLAG_IGNORE_CPU;
if(token.find('x') != string::npos) m_flags |= FLAG_NEEDS_SIGNING;
if(token.find('k') != string::npos) m_flags |= FLAG_FIXUP_LIKE_KERNEL;
if(token.find('r') != string::npos) m_flags |= FLAG_COMPRESS_RESOURCES;
if(token.find('m') != string::npos) m_flags |= IMAGE_SCN_MEM_NOT_PAGED;
if(token.find('l') != string::npos) m_flags &= ~FLAG_SPLIT_CODE;
}
if(token.find('h') != string::npos) m_file_attributes |= FILE_ATTRIBUTE_HIDDEN;
if(token.find('s') != string::npos) m_file_attributes |= FILE_ATTRIBUTE_SYSTEM;
if(token.find('n') != string::npos) m_file_attributes |= MODULE_ATTR_NOT_TRUSTED;
if(token.find('d') != string::npos) m_file_attributes |= MODULE_ATTR_NODEBUG;
if(token.find('u') != string::npos) m_file_attributes &= ~FILE_ATTRIBUTE_COMPRESSED;
if(token.find('c') != string::npos) m_file_attributes |= FILE_ATTRIBUTE_COMPRESSED;
CompressorList::iterator citr = compressor_list.begin();
for(char i = '0'; i <= '9'; i++, citr++){
if(token.find(i) != string::npos){
m_compressor = citr;
break;
}
}
}
/*****************************************************************************
set()
in:
StringList token_list - vector of string tokens from parsed line
MemoryList memory_list - the already complete memory list so the we
know what section this file belongs in
bool compressed - is this file meant to be compressed
out:
boolean value indicating success
desc:
initializes the class variables and sets the file attributes
******************************************************************************/
bool
File::set(
const StringList &token_list,
MemoryList &memory_list,
CompressorList &compressor_list)
{
// hack for paths with ('s and )'s in them!
StringList fudged_list;
for(unsigned i = 0; i < token_list.size(); i++){
if(i + 4 < token_list.size() && token_list[i + 1] == "("){
string token = token_list[i] + token_list[i + 1] + token_list[i + 2] + token_list[i + 3] + token_list[i + 4];
fudged_list.push_back(token);
i += 4;
}
else
fudged_list.push_back(token_list[i]);
}
if(fudged_list.size() < 3 || fudged_list.size() > 5){
cerr << "Error: Incorrect number of tokens found parsing file\n";
cerr << " found: ";
for(unsigned i = 0; i < fudged_list.size(); i++)
cerr << "'" << fudged_list[i] << "' ";
cerr << endl;
return false;
}
// takes a line like:
// nk.exe c:\wince400\public\projects\nkexe\SH3_rel\nk.exe NK SH
// or:
// public\projects\nkexe\SH3_rel\nk.exe c:\wince400\public\projects\nkexe\SH3_rel\nk.exe NK SH
m_name = fudged_list[0];
if(m_name.rfind("\\")){
m_build_path = m_name.substr(0, m_name.rfind("\\") + 1);
m_name.erase(0, m_build_path.size());
}
m_release_path = fudged_list[1];
// find an iterator to the memory section specified from the memory_list
m_memory_section = find(memory_list.begin(), memory_list.end(), Memory(fudged_list[2]));
if(m_memory_section == memory_list.end()){
cerr << "Error: Unknown memory type found '" << fudged_list[2] << "'\n";
return false;
}
// init default compressor
m_compressor = compressor_list.begin();
if(fudged_list.size() >= 4){
if(fudged_list[3] == MODULE) set_module();
if(fudged_list[3] == FILE) set_file();
if(fudged_list[3] == MODULE || fudged_list[3] == FILE){
if(fudged_list.size() >= 5)
convert_file_attributes_to_flags(fudged_list[4], compressor_list);
}
else
convert_file_attributes_to_flags(fudged_list[3], compressor_list);
}
return get_file_info();
}
bool
File::set(
const string &file,
const string &release_path,
DWORD attributes,
const MemoryList::iterator memory_section,
const CompressorList::iterator compressor)
{
m_name = file;
m_release_path = release_path;
m_memory_section = memory_section;
m_file_attributes = attributes;
m_compressor = compressor;
return get_file_info();
}
/*****************************************************************************
load()
in:
none
out:
boolean value indicating success
desc:
******************************************************************************/
bool
File::load()
{
if(GetFileAttributes(m_release_path.c_str()) == -1){
cerr << "Error: Could not find file '" << m_release_path << "'\n";
return false;
}
ifstream file(m_release_path.c_str(), ios::in|ios::binary);
if(file.bad()){
cerr << "Error: Could not open '" << m_release_path << "' for reading\n";
return false;
}
get_file_info();
file.read((char *)m_data.user_fill(m_file_size), m_file_size);
if(file.fail()){
cerr << "Error: Failed reading file " << m_release_path << endl;
return false;
}
return true;
}
/*****************************************************************************
compress()
in:
none
out:
boolean value indicating success
desc:
******************************************************************************/
bool File::compress(bool comp){
// no compression wanted or zero length
if(!comp || !m_file_size)
m_file_attributes &= ~FILE_ATTRIBUTE_COMPRESSED;
// no compressed attribute
if(!(m_file_attributes & FILE_ATTRIBUTE_COMPRESSED))
return true;
// compress the section
Data compressed_data;
DWORD compressed_size;
assert(s_page_size);
compressed_size = m_compressor->cecompress(m_data.ptr(),
m_file_size,
compressed_data.user_fill(m_file_size),
m_file_size - 1,
1,
s_page_size);
if(compressed_size == -1) // failed
m_file_attributes &= ~FILE_ATTRIBUTE_COMPRESSED; // we are no longer considered compressed
else // succeeded
m_data.set(compressed_data.ptr(), compressed_size); // chose not to use = operator to allow for explicit resize
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -