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

📄 newpdb.cpp

📁 当前支持 16-bit, 32-bit and 64-bit 的二进制文件
💻 CPP
字号:
// newpdb.cpp
// Copyright (C) 2008,2009 Willow Schlanger

#include "newpdb.h"
#include "util.h"
#include <cstring>

namespace ceres
{

// private
struct PACKED(pdb_header_t)
{
    U4 dPageBytes;				// 0x0400
    U4 dFlagPage;				// 0x0002
    U4 dFilePages;				// file size / dPageBytes
    U4 dRootBytes;				// stream directory size
    U4 dReserved;				// 0
    U4 adIndexPages[1];			// root page index pages
};

static const char signature[] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0";
static const UINT sig_len = 32;
static const UINT header_len = sig_len + 4 * 5;

static bool check_header(U1 *buf, U8 size)
{
	if(size < sig_len)
		return false;
	for(UINT x = 0; x < sig_len; ++x)
		if(buf[x] != signature[x])
			return false;
	return true;
}

// public
void read_pdb(std::string filename, pdb_t &streams)
{
	U1 *buf;
	U8 buf_size;
	streams.clear();
	
	int status;
	buf = load_file(filename.c_str(), buf_size, status);
	
	if(status != 0)
		return;
	if(!check_header(buf, buf_size))
	{
		delete [] buf;
		return;
	}
	
	pdb_header_t *header = (pdb_header_t *)((&buf[0]) + sig_len);
	
	if(header->dRootBytes == (U4)(-1) || header->dRootBytes == 0)
	{
		delete [] buf;
		return;
	}
	
	std::vector<U1> index;
	U4 root_pages = (header->dRootBytes + header->dPageBytes - 1) / header->dPageBytes;
	U4 index_bytes = 4 * root_pages;
	U4 index_pages = (index_bytes + header->dPageBytes - 1) / header->dPageBytes;
	index.resize(header->dPageBytes * index_pages);
	
	for(U4 u = 0; u < index_pages; ++u)
	{
		std::memcpy(&index[u * header->dPageBytes], &buf[header->dPageBytes * header->adIndexPages[u]], header->dPageBytes);
	}
	
	index.resize(index_bytes);
	
	// Now read the root.
	std::vector<U1> root;
	root.resize(root_pages * header->dPageBytes);
	
	U4 *aindex = (U4 *)(&index[0]);
	for(U4 u = 0; u < root_pages; ++u)
	{
		std::memcpy(&root[u * header->dPageBytes], &buf[header->dPageBytes * aindex[u]], header->dPageBytes);
	}
	
	root.resize(header->dRootBytes);
	
	U4 *bindex = (U4 *)(&root[0]);
	
	for(U4 i = 0, j = 0; i < bindex[0]; ++i)
	{
		streams.push_back(std::vector<U1>());
		if(bindex[i + 1] == (U4)(-1))
			continue;
		U4 num_pages = (bindex[i + 1] + header->dPageBytes - 1) / header->dPageBytes;
		streams.back().resize(num_pages * header->dPageBytes);
		U4 *cindex = &bindex[1 + bindex[0]];
		for(U4 k = 0; k < num_pages; ++k, ++j)
		{
			memcpy(&(streams.back()[k * header->dPageBytes]), &buf[cindex[j] * header->dPageBytes], header->dPageBytes);
		}
		streams.back().resize(bindex[i + 1]);
	}
	
	delete [] buf;
}

//---

// public
int get_stream_n(pdb_t &pdb, U4 n)
{
	if(pdb.size() <= n || pdb[n].empty())
		return -1;
	return n;
}

static bool stream_is_sym(U1 *data, UINT size)
{
	UINT ofs;
	U2 len, type;
	bool found_110e = false;
	for(ofs = 0; ofs < size;)
	{
		if(size - ofs < 4)
			return false;
		len = *(U2 *)(data + ofs);
		type = *(U2 *)(data + ofs + 2);
		if(type == 0x110e)
			found_110e = true;
		ofs += (UINT)len + 2;
	}
	return (ofs == size) && found_110e;
}

// public
int get_stream_sym(pdb_t &pdb)
{
	int stream = -1;
	if(pdb.size() > 14 && pdb[14].size() >= 4)
	{
		U1 *data = &(pdb[14])[0];
		U2 len = *(U2 *)(data);
		U2 type = *(U2 *)(data + 2);
		if(type != 0)
			stream = 14;
	}
	if(stream == -1 && pdb.size() > 8)
		stream = 8;
	if(stream != -1)
	{
		if(!stream_is_sym(&(pdb[stream])[0], pdb[stream].size()))
			stream = -1;
	}
	if(stream == -1)
	{
		UINT u;
		for(u = 1; u < pdb.size(); ++u)
		{
			if(u != 2 && stream_is_sym(&(pdb[u])[0], pdb[stream].size()))
			{
				stream = (int)u;
				break;
			}
		}
	}
	return stream;
}

}	// namespace ceres

⌨️ 快捷键说明

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