⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -