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.
 
 
 
 
 
 

324 lines
11 KiB

//+-------------------------------------------------------------------------
//
// Microsoft OLE
// Copyright (C) Microsoft Corporation, 1996 - 1997.
//
// File: ntutil.cpp
//
// Contents: Utility functions for NTFS drives.
// These functions will probably not be
// available for Mac, Win9x, so should be
// stubbed out in the header file as such.
//
// Functions:
// ConversionVerification
// VerifyNssfile
//
// History: 01/19/98 SCousens Created
//
//--------------------------------------------------------------------------
#include <dfheader.hxx>
#pragma hdrstop
// Debug Object declaration
DH_DECLARE;
// Must be at least NT5 (not mac, not win9x, not nt4 etc)
#if defined(_WIN32_WINNT) && (_WIN32_WINNT>=0x0500)
/*******************************************************************/
/* */
/* WARNING: */
/* ConversionVerification, VerifyNssfile */
/* must be the LAST functions in this file. */
/* We redefine stuff that must not affect the rest */
/* of the functions. */
/* of the functions. */
/* */
/*******************************************************************/
#ifdef _HOOK_STGAPI_
#undef StgCreateDocfile
#undef StgOpenStorage
#endif /* _HOOK_STGAPI_ */
//+-------------------------------------------------------------------------
// Function: ConversionVerification
//
// Synopsis: Opens a nssfile as docfile and then as nssfile
// and calculates CRC each time. If CRC is different
// then there is a problem with the conversion driver
//
// Arguments: [pFileName] - Name of Docfile
// [dwCRCexp] - Expected CRC (default=0)
//
// Returns: S_OK if all went well and CRCs match
// or E_FAIL if something else went wrong
// (CRCs dont match, ulRef not 0 after Release)
//
// History: 28-Jan-97 SCousens Created.
//
// Notes: - NSSFile must previously be closed, or access violations
// may occur calculating CRC.
//--------------------------------------------------------------------------
HRESULT ConversionVerification (LPTSTR pFileName, DWORD dwCRCexp)
{
DWORD dwCRCdf = 0, dwCRCnss = 0;
IStorage *pIStorage;
HRESULT hr = S_OK;
ULONG ul;
LPOLESTR pOleStrTemp = NULL;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("ConversionVerification"));
DH_VDATESTRINGPTR (pFileName);
// Convert TCHAR to OLECHAR
hr = TStringToOleString(pFileName, &pOleStrTemp);
DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
// Open as docfile, calc CRC for file and close it.
if(S_OK == hr)
{
hr = StgOpenStorageEx (pOleStrTemp,
STGM_READ | STGM_SHARE_EXCLUSIVE,
STGFMT_DOCFILE,
0,
NULL,
NULL,
IID_IStorage,
(void**)&pIStorage);
DH_HRCHECK (hr, TEXT("Cnv:StgOpenStorageEx"));
if (S_OK == hr)
{
hr = CalculateCRCForDocFile(pIStorage,
VERIFY_INC_TOPSTG_NAME,
&dwCRCdf);
DH_HRCHECK (hr, TEXT("CalculateCRCForDocFile"));
}
if (S_OK != hr || 0 == dwCRCdf)
{
DH_LOG((LOG_INFO, TEXT("Cnv:CalculateCRCForDocFile on docfile failed, hr=0x%lx.\n"), hr));
}
if (NULL != pIStorage)
{
ul = pIStorage->Release ();
DH_ASSERT (0 == ul);
pIStorage = NULL;
}
}
// Open normally (as nssfile), calc CRC for the file close it.
if (S_OK == hr)
{
hr = StgOpenStorage (pOleStrTemp,
NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE,
NULL,
0,
&pIStorage);
DH_HRCHECK (hr, TEXT("Cnv:StgOpenStorage"));
if (S_OK == hr)
{
hr = CalculateCRCForDocFile(pIStorage,
VERIFY_INC_TOPSTG_NAME,
&dwCRCnss);
DH_HRCHECK (hr, TEXT("CalculateCRCForDocFile"));
}
if (S_OK != hr || 0 == dwCRCnss)
{
DH_LOG((LOG_INFO, TEXT("Cnv:CalculateCRCForDocFile on nssfile failed, hr=0x%lx.\n"), hr));
}
if (NULL != pIStorage)
{
ul = pIStorage->Release ();
DH_ASSERT (0 == ul);
pIStorage = NULL;
}
}
// spew
if (S_OK == hr &&
dwCRCnss == dwCRCdf &&
0 != dwCRCdf &&
(0 == dwCRCexp || dwCRCexp == dwCRCdf))
{
DH_LOG((LOG_INFO, TEXT("Conversion verification passed.\n")) );
}
else
{
hr = (S_OK != hr) ? hr : E_FAIL; //set it only if not already set.
DH_LOG((LOG_INFO,
TEXT("Conversion verification failed, hr=0x%lx.\n"),
hr) );
}
if (NULL != pOleStrTemp)
{
delete pOleStrTemp;
pOleStrTemp = NULL;
}
return hr;
}
//+-------------------------------------------------------------------------
// Function: VerifyNssfile
//
// Synopsis: Verify an nssfile is indeed an nssfile by checking:
// 1. reparse point is set (spew if not)
// 2. header is valid (spew if df or unknown, and set hr)
// Verify the reparse point is set.
// Open the file directly with REPARSE flag (to prevent cnss from
// converting it). Read the header and make sure it looks like a
// real nssfile by checking the file signatures.
//
// Arguments: [pszPathname] - full path to the file to be checked
//
// Returns: S_OK, else some sort of error.
// We set the following if file is df or unknown
// ERROR_INVALID_DATA - if file is a DOCFILE
// 13L - The data is invalid
// ERROR_FILE_INVALID - if file is UNKNOWN (not df or nss)
// 1006L - The volume for a file has been externally
// altered so that the opened file is no longer valid
// ERROR_INVALID_EA_NAME - no reparse point (if others valid)
// 254L - The specified extended attribute name was invalid.
//
// History: 24-Jul-97 SCousens Created.
//
// Notes: - NSSFile must previously be closed, or file share
// access violations may occur reading the header.
//--------------------------------------------------------------------------
#define NSSFILE_SIGNATURE 0x444D4F30
#define DOCFILE_SIGNATURE1 0xE011CFD0 //0xD0CF11E0 little endian
#define DOCFILE_SIGNATURE2 0xE11AB1A1 //0xA1B11AE1 little endian
HRESULT VerifyNssfile (LPTSTR pszPathname)
{
HRESULT hr = S_OK;
HANDLE hnd;
ULONG culRead;
ULONG ulAttr;
struct _structFileHeader {
ULONG ulSig1;
ULONG ulSig2;
} sFileHeader;
DH_FUNCENTRY (&hr, DH_LVL_DFLIB, TEXT("VerifyNssfile"));
/* check the file attributes and look for reparse attribute */
ulAttr = GetFileAttributes (pszPathname);
DH_TRACE ((DH_LVL_DFLIB,
TEXT("VerifyNssfile; Attributes retrieved:%#lx"),
ulAttr));
if ((ULONG)-1 == ulAttr)
{
DH_TRACE ((DH_LVL_ERROR,
TEXT("VerifyNssfile; Unable to get attributes for %s"),
pszPathname));
hr = HRESULT_FROM_WIN32(GetLastError());
DH_HRCHECK (hr, TEXT("GetFileAttributes"));
return hr;
}
/* attempt to open the file */
hnd = CreateFile(pszPathname,
GENERIC_READ,
FILE_SHARE_READ,
NULL, // security descriptor
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OPEN_REPARSE_POINT,
NULL); //hTemplateFile
if (INVALID_HANDLE_VALUE == hnd)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
DH_HRCHECK (hr, TEXT("CreateFile"));
/* if we succeeded, read the header */
if (S_OK == hr)
{
BOOL fErr;
fErr = ReadFile (hnd, &sFileHeader, sizeof (sFileHeader), &culRead, NULL);
if (FALSE == fErr)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
DH_HRCHECK (hr, TEXT("ReadFile"));
DH_TRACE ((DH_LVL_DFLIB, TEXT("Read %ld bytes from file"), culRead));
}
/* check the header looks like an nss header */
if (S_OK == hr)
{
if (sFileHeader.ulSig1 != NSSFILE_SIGNATURE)
{
if (sFileHeader.ulSig1 == DOCFILE_SIGNATURE1 &&
sFileHeader.ulSig2 == DOCFILE_SIGNATURE2)
{
hr = ERROR_INVALID_DATA;
DH_TRACE ((DH_LVL_TRACE1, TEXT("WARNING!!! VerifyNssfile; File appears to be a DOCFILE")));
}
else
{
hr = ERROR_FILE_INVALID;
DH_TRACE ((DH_LVL_TRACE1, TEXT("WARNING!!! VerifyNssfile; File is INVALID nssfile or docfile!")));
}
}
else
{
DH_TRACE ((DH_LVL_DFLIB, TEXT("VerifyNssfile; File appears to be valid nssfile")));
}
}
// If nssfile, but no reparse point, its still not valid!
// It is impossible to have an nssfile with a reparse
// point on an NTFS4 volume.
// It is impossible to have an nssfile on a FAT volume.
if (0 == (FILE_ATTRIBUTE_REPARSE_POINT & ulAttr))
{
DH_TRACE ((DH_LVL_TRACE1,
TEXT("WARNING!!! VerifyNssfile; File *NOT* have reparse point set!")));
if (S_OK == hr)
{
hr = ERROR_INVALID_EA_NAME;
}
}
// close the file
if (INVALID_HANDLE_VALUE != hnd)
{
HRESULT hr2 = S_OK;
if (FALSE == CloseHandle(hnd))
{
hr2 = HRESULT_FROM_WIN32(GetLastError());
}
DH_HRCHECK (hr2, TEXT("CloseHandle"));
}
// if there is a problem, say what file caused it.
if (S_OK != hr)
{
DH_TRACE ((DH_LVL_TRACE1,
TEXT("WARNING!!! File causing problem: %s"),
pszPathname));
}
return hr;
}
/*******************************************************************/
/* */
/* WARNING: */
/* ConversionVerification, VerifyNssfile */
/* must be the LAST function in this file. */
/* We redefine stuff that must not affect the rest */
/* of the functions. */
/* */
/*******************************************************************/
#endif // WINNT5+