Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

368 lines
8.6 KiB

#include "pch.h"
typedef enum {
fncRead = 0,
fncWrite,
fncNone
};
int parseargs(int argc, char **argv, char *pdb, char *input, char *stream, DWORD size);
int getcontent(char *filename, char **content);
int ProcessPDB6(int argc, char **argv, char **env);
#define fileexists(path) (GetFileAttributes(path) != 0xFFFFFFFF)
extern "C" int __cdecl main(int argc, char **argv, char **env)
{
BOOL rc;
int fnc = fncNone;
char pdbname[MAX_PATH];
char input[MAX_PATH];
char streamname[MAX_PATH];
PDB *pdb;
EC ec;
char errormsg[cbErrMax];
Stream* pstream;
char *buf = NULL;
long size;
long cb;
bool success = false;
fnc = parseargs(argc, argv, pdbname, input, streamname, MAX_PATH);
if (fnc == fncNone)
return success;
*errormsg = 0;
rc = PDBOpen(pdbname,
(fnc == fncRead) ? "r" : "w",
0,
&ec,
errormsg,
&pdb);
if (!rc)
{
if (ec == ERROR_BAD_FORMAT)
return ProcessPDB6(argc, argv, env);
printf("error 0x%x opening %s\n", ec, pdbname);
return success;
}
rc = PDBOpenStream(pdb, streamname, &pstream);
if (!rc)
{
printf( "Could not open stream %s in %s.\n", streamname, pdbname);
goto cleanup;
}
if (fnc == fncWrite)
{
size = getcontent(input, &buf);
if (!size)
goto cleanup;
rc = StreamReplace(pstream, (void *)buf, (DWORD)size);
if ( !rc )
{
printf( "StreamReplace failed for %s(%s).\n", pdbname, streamname);
goto cleanup;
}
rc = PDBCommit( pdb );
if ( !rc ) {
printf( "PDBCommit failed for %s.\n", pdbname);
goto cleanup;
}
success = true;
}
else if (fnc == fncRead)
{
size = StreamQueryCb(pstream);
if (!size)
goto cleanup;
buf = (char *)calloc(size + 1, sizeof(char));
if (!buf)
goto cleanup;
cb = size;
rc = StreamRead(pstream, 0, buf, &cb);
if (!rc)
goto cleanup;
if (cb != size)
goto cleanup;
printf(buf);
success = true;
}
cleanup:
if (buf)
free(buf);
if (pdb)
rc = PDBClose(pdb);
return success ? 0 : -1;
}
bool parsesz(char *sz, char *file, DWORD size)
{
if (*(sz + 2) != ':')
return false;
StringCchCopy(file, size, sz + 3);
return (*file) ? true : false;
return (GetFileAttributes(file) == 0xFFFFFFFF) ? false : true;
}
int parseerror()
{
printf("pdbstr -r/w -p:PdbFileName -i:StreamFileName -s:StreamName\n");
return fncNone;
}
int parseargs(int argc, char **argv, char *pdb, char *input, char *stream, DWORD size)
{
// all input strings must be the same size
int i;
int rc;
char *sz;
rc = fncNone;
assert(pdb && input && stream);
*pdb = *input = *stream = 0;
for (i = 0; i < argc; i++, argv++)
{
if (!i)
continue;
sz = *argv;
if (*sz == '-' || *sz == '/')
{
switch(*(sz + 1))
{
case 'r':
case 'R':
rc = fncRead;
break;
case 'w':
case 'W':
rc = fncWrite;
break;
case 'p':
case 'P':
if (!parsesz(sz, pdb, size))
return parseerror();
break;
case 'i':
case 'I':
if (!parsesz(sz, input, size))
return parseerror();
break;
case 's':
case 'S':
if (!parsesz(sz, stream, size))
return parseerror();
break;
default:
return parseerror();
}
}
}
if (rc == fncNone)
return parseerror();
if (!fileexists(pdb))
return parseerror();
if (!*stream)
return parseerror();
if ((rc == fncWrite) && !fileexists(input))
return parseerror();
return rc;
}
int getcontent(char *filename, char **buf)
{
HANDLE hptr;
DWORD size;
DWORD cb;
LPSTR p;
bool success = false;
hptr = CreateFile(filename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hptr == INVALID_HANDLE_VALUE)
return 0;
// test validity of file pointer
size = GetFileSize(hptr, NULL);
if (!size)
goto cleanup;
// allocate space for file
*buf = (char *)calloc(size, sizeof(char));
if (!*buf)
goto cleanup;
// read it in
if (!ReadFile(hptr, *buf, size, &cb, 0))
goto cleanup;
if (cb != size)
goto cleanup;
success = true;
cleanup:
// done
if (hptr)
CloseHandle(hptr);
if (!success)
{
if (*buf)
free(*buf);
return 0;
}
return size;
}
// all this stuff handles PDB6 format
typedef BOOL (PDBCALL *PfnPDBOpenStream)(PDB* ppdb, const char* szStream, OUT Stream** ppstream);
typedef BOOL (PDBCALL *PfnStreamReplace)(Stream* pstream, void* pvBuf, long cbBuf);
typedef BOOL (PDBCALL *PfnPDBCommit)(PDB* ppdb);
typedef BOOL (PDBCALL *PfnPDBClose)(PDB* ppdb);
PfnPDBOpen fnPDBOpen = NULL;
PfnPDBOpenStream fnPDBOpenStream = NULL;
PfnStreamReplace fnStreamReplace = NULL;
PfnPDBCommit fnPDBCommit = NULL;
PfnPDBClose fnPDBClose = NULL;
int ProcessPDB6(int argc, char **argv, char **env)
{
BOOL rc;
int fnc = fncNone;
char pdbname[MAX_PATH];
char input[MAX_PATH];
char streamname[MAX_PATH];
PDB *pdb;
EC ec;
char errormsg[cbErrMax];
Stream* pstream;
char *buf = NULL;
long size;
long cb;
bool success = false;
HINSTANCE hmspdb;
fnc = parseargs(argc, argv, pdbname, input, streamname, MAX_PATH);
if (fnc == fncNone)
return success;
hmspdb = LoadLibrary("mspdb60.dll");
if (!hmspdb)
{
printf("error 0x%x loading mspdb60.dll\n", GetLastError());
return success;
}
fnPDBOpen = (PfnPDBOpen)GetProcAddress(hmspdb, "PDBOpen");
fnPDBOpenStream = (PfnPDBOpenStream)GetProcAddress(hmspdb, "PDBOpenStream");
fnStreamReplace = (PfnStreamReplace)GetProcAddress(hmspdb, "StreamReplace");
fnPDBCommit = (PfnPDBCommit)GetProcAddress(hmspdb, "PDBCommit");
fnPDBClose = (PfnPDBClose)GetProcAddress(hmspdb, "PDBClose");
if (!fnPDBOpen || !fnPDBOpenStream || !fnStreamReplace || !fnPDBCommit || !fnPDBClose)
{
printf("error 0x%x searching for exports in mspdb60.dll\n", GetLastError());
return success;
}
*errormsg = 0;
rc = fnPDBOpen(pdbname,
(fnc == fncRead) ? "r" : "w",
0,
&ec,
errormsg,
&pdb);
if (!rc)
{
printf("error 0x%x opening %s\n", ec, pdbname);
return success;
}
rc = fnPDBOpenStream(pdb, streamname, &pstream);
if (!rc)
{
printf( "Could not open stream %s in %s.\n", streamname, pdbname);
goto cleanup;
}
if (fnc == fncWrite)
{
size = getcontent(input, &buf);
if (!size)
goto cleanup;
rc = fnStreamReplace(pstream, (void *)buf, (DWORD)size);
if ( !rc )
{
printf( "StreamReplace failed for %s(%s).\n", pdbname, streamname);
goto cleanup;
}
rc = fnPDBCommit( pdb );
if ( !rc ) {
printf( "PDBCommit failed for %s.\n", pdbname);
goto cleanup;
}
success = true;
}
else if (fnc == fncRead)
{
size = StreamQueryCb(pstream);
if (!size)
goto cleanup;
buf = (char *)calloc(size + 1, sizeof(char));
if (!buf)
goto cleanup;
cb = size;
rc = StreamRead(pstream, 0, buf, &cb);
if (!rc)
goto cleanup;
if (cb != size)
goto cleanup;
printf(buf);
success = true;
}
cleanup:
if (buf)
free(buf);
if (pdb)
rc = fnPDBClose(pdb);
return success ? 0 : -1;
}