Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

337 lines
6.7 KiB

//
// mreutil.cpp
//
// utility functions
//
#include "pdbimpl.h"
#include "mrimpl.h"
struct LI {
DWORD low;
DWORD high;
};
union QW {
LI li;
FILETIME ft;
QWORD qw;
};
BOOL
FFileInfo ( SZC szFile, MREFT & mreft, QWORD & cbfile ) {
HANDLE hfind;
BOOL fRet = fFalse;
WIN32_FIND_DATA find;
mreft.qwft = 0;
cbfile = 0;
hfind = ::FindFirstFile ( szFile, &find );
if ( hfind != INVALID_HANDLE_VALUE ) {
QW qwT;
mreft.ft = find.ftLastWriteTime;
qwT.li.low = find.nFileSizeLow;
qwT.li.high = find.nFileSizeHigh;
cbfile = qwT.qw;
fRet = fTrue;
verify ( ::FindClose ( hfind ) );
}
return fRet;
}
BOOL
FFileInfo ( HANDLE hFile, MREFT & mreft, QWORD & cbFile ) {
BY_HANDLE_FILE_INFORMATION hfi;
BOOL fRet = fFalse;
precondition ( hFile != INVALID_HANDLE_VALUE );
mreft.qwft = 0;
cbFile = 0;
if ( ::GetFileInformationByHandle ( hFile, &hfi ) ) {
QW qwT;
mreft.ft = hfi.ftLastWriteTime;
qwT.li.low = hfi.nFileSizeLow;
qwT.li.high = hfi.nFileSizeHigh;
cbFile = qwT.qw;
fRet = fTrue;
}
return fRet;
}
SZ
SzCanonFilename ( SZ szfile ) {
_tcslwr ( szfile );
SZ szT = _tcschr ( szfile, '/' );
for ( ; szT != NULL; szT = _tcschr ( szT, '/' ) ) {
*szT = '\\';
}
return szfile;
}
//
// MRFIBuf implementation
//
BOOL
MRFIBuf::FInitEmpty() {
m_pmre->m_mrelog.LogNote (
"Note: initializing MRFIBuf empty.\n"
);
memset ( &m_mrfi, 0, sizeof MRFI );
m_mrfi.strmhdr.dwSig = sigFileStream;
m_mrfi.strmhdr.cb = sizeof MRFI;
m_setniFile.reset();
m_mpniclassdep.reset();
m_setniBoringClass.reset();
return fTrue;
}
BOOL
MRFIBuf::FInitFromPb ( PB pb ) {
precondition ( m_pmre );
m_mrfi = *(MRFI*) pb;
if ( m_mrfi.strmhdr.dwSig != sigFileStream || m_mrfi.strmhdr.cb <= sizeof MRFI ) {
// possible corrupt stream
m_pmre->m_mrelog.LogNote ( "Note: Warning: failure in MRFIBuf header.\n" );
FInitEmpty();
return fFalse;
}
BOOL fRet = fFalse;
PB pbT;
m_setniFile.reset();
m_setniBoringClass.reset();
m_mpniclassdep.reset();
m_pmre->m_mrelog.LogNote (
"Note:\tmrfi.offFiledeps = %d,\n\tmrfi.offClassdeps = %d,\n\tmrfi.offBoringClasses = %d.\n",
m_mrfi.offFiledeps,
m_mrfi.offClassdeps,
m_mrfi.offBoringClasses
);
pbT = pb + m_mrfi.offFiledeps;
fRet = m_mrfi.offFiledeps && m_setniFile.reload ( &pbT );
pbT = pb + m_mrfi.offClassdeps;
fRet &= m_mrfi.offClassdeps && m_mpniclassdep.reload ( &pbT );
pbT = pb + m_mrfi.offBoringClasses;
fRet &= m_mrfi.offBoringClasses && m_setniBoringClass.reload ( &pbT );
m_pmre->m_mrelog.LogNote (
"Note: Loading MRFIBuf from PB was %ssuccessful.\n",
fRet ? "" : "un"
);
return fRet;
}
BOOL
MRFIBuf::FStoreIntoBuf ( Buffer & buf ) {
SetOffsets();
buf.Free();
return
buf.SetInitAlloc ( CbDepData() ) &&
buf.Append ( PB(&m_mrfi), sizeof(m_mrfi) ) &&
m_setniFile.save ( &buf ) &&
m_mpniclassdep.save ( &buf ) &&
m_setniBoringClass.save ( &buf )
;
}
BOOL
MRFIBuf::FInitFromStream ( Stream * pstream ) {
precondition ( pstream );
BOOL fRet = fFalse;
CB cb = pstream->QueryCb();
if ( cb <= sizeof MRFI ) {
// invalid or empty stream
m_pmre->m_mrelog.LogNote ( "Note: size of MRFIBuf stream too small.\n" );
FInitEmpty();
}
else {
Buffer buf;
if ( buf.Reserve ( cb ) && pstream->Read2 ( 0, PV(buf.Start()), cb ) ) {
fRet = FInitFromPb ( PB(buf.Start()) );
}
else {
m_pmre->m_mrelog.LogNote (
"Note: failed to reserve %d bytes or read from stream.\n",
cb
);
FInitEmpty();
}
}
return fRet;
}
BOOL
MRFIBuf::FInitFromDepData ( PDepData pdepdata ) {
precondition ( pdepdata );
BOOL fRet = fFalse;
CB cb = pdepdata->cb;
if ( cb <= sizeof MRFI ) {
// invalid or empty depdata
FInitEmpty();
}
else {
// cache the current (correct!) file ni's
NI niSrc, niTarg;
niSrc = m_mrfi.niFile;
niTarg = m_mrfi.niTarg;
fRet = FInitFromPb ( pdepdata->rgb );
// restore the file ni's
SetNiFile ( niSrc, niTarg );
}
return fRet;
}
BOOL
MRFIBuf::FStoreIntoDepData ( PDepData pdepdata ) {
BOOL fRet = fFalse;
size_t cbReq = CbDepData() + sizeof DepData;
if ( pdepdata->cb >= cbReq ) {
Buffer buf;
fRet = FStoreIntoBuf ( buf );
if ( fRet ) {
memcpy ( pdepdata->rgb, buf.Start(), cbReq - sizeof DepData );
}
}
pdepdata->cb = cbReq;
return fRet;
}
BOOL
MRFIBuf::FAppendToStream ( Stream * pstream ) {
precondition ( pstream );
CB cbStreamOrig = pstream->QueryCb();
OFF offWrite = cbStreamOrig;
Buffer buf;
if ( FStoreIntoBuf ( buf ) ) {
assert ( CbDepData() <= buf.Size() );
return pstream->Append ( PV(buf.Start()), CbDepData() );
}
return fFalse;
}
BOOL
MRFIBuf::FReplaceStream ( Stream * pstream ) {
precondition ( pstream );
pstream->Truncate ( 0 );
return FAppendToStream ( pstream );
}
BOOL
MRFIBuf::FAddClassDep ( NI niClass, TI tiClass, SZC szMember, DEPON deponHow, DWORD dwLine ) {
precondition ( niClass != niNil );
debug ( SZC szClass = m_pmre->SzFromNi ( niClass ) );
assert ( FTiIsClass ( tiClass ) );
assert ( FNotFwdRef ( tiClass ) );
CLASSDEP * pcd = NULL;
if ( !m_mpniclassdep.map ( niClass, &pcd ) ) {
if ( m_mpniclassdep.add ( niClass, CLASSDEP ( niClass, tiClass, deponHow ) ) ) {
m_mpniclassdep.map ( niClass, &pcd );
}
}
if ( pcd ) {
// update the data
assert ( pcd->ti == tiClass );
pcd->depon |= deponHow;
if ( szMember ) {
pcd->bvNames.SetIBit ( ModHashSz ( szMember, cbitsName ), fTrue );
}
}
return NULL != pcd;
}
BOOL
MRFIBuf::FTiIsClass ( TI ti ) {
TPI * ptpi = m_pmre->m_ptpi;
BOOL fRet = fTrue;
PtypeRec ptypeRec;
if ( ptpi->QueryPbCVRecordForTi ( ti, PPB(&ptypeRec) ) ) {
unsigned leaf = ptypeRec->leaf;
fRet = leaf == LF_STRUCTURE || leaf == LF_CLASS || leaf == LF_UNION;
}
return fRet;
}
BOOL
MRFIBuf::FNotFwdRef ( TI ti ) {
TPI * ptpi = m_pmre->m_ptpi;
BOOL fRet = fTrue;
PtypeRec ptypeRec;
if ( ptpi->QueryPbCVRecordForTi ( ti, PPB(&ptypeRec) ) ) {
unsigned leaf = ptypeRec->leaf;
fRet = leaf == LF_STRUCTURE || leaf == LF_CLASS || leaf == LF_UNION;
if ( fRet ) {
PlfClass plfClass = PlfClass(&ptypeRec->leaf);
fRet = !plfClass->property.fwdref;
}
}
return fRet;
}
BOOL
MRFIBuf::FmergeClassDeps ( const MRFIBuf & mrfibuf ) {
BOOL fRet = fTrue;
EnumMapNiClassdep e(mrfibuf.m_mpniclassdep);
NI niPrev;
CLASSDEP * pcdPrev;
CLASSDEP * pcdCur;
while ( fRet && e.next() ) {
e.get ( &niPrev, &pcdPrev );
assert ( niPrev == pcdPrev->Ni() );
if ( m_mpniclassdep.map ( niPrev, &pcdCur ) ) {
// already existing in the new class deps. Or in the bits
assert ( niPrev == pcdCur->Ni() );
*pcdCur |= *pcdPrev;
}
else {
// add in the previous one.
fRet = m_mpniclassdep.add ( niPrev, *pcdPrev );
}
}
return fRet;
}
SZC
SzFromNiDbg ( NameMap * pnmp, NI ni ) {
SZC sz;
pnmp->getName ( ni, &sz );
return sz;
}