📄 newpdb.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 + -