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.
 
 
 
 
 
 

625 lines
16 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: filesp.cpp
//
// Contents: File Scheme Provider
//
// History: 08-Aug-97 kirtd Created
// 01-Jan-02 philh Changed to internally use UNICODE Urls
//
//----------------------------------------------------------------------------
#include <global.hxx>
//+---------------------------------------------------------------------------
//
// Function: FileRetrieveEncodedObject
//
// Synopsis: retrieve encoded object via Win32 File I/O
//
//----------------------------------------------------------------------------
BOOL WINAPI FileRetrieveEncodedObject (
IN LPCWSTR pwszUrl,
IN LPCSTR pszObjectOid,
IN DWORD dwRetrievalFlags,
IN DWORD dwTimeout,
OUT PCRYPT_BLOB_ARRAY pObject,
OUT PFN_FREE_ENCODED_OBJECT_FUNC* ppfnFreeObject,
OUT LPVOID* ppvFreeContext,
IN HCRYPTASYNC hAsyncRetrieve,
IN PCRYPT_CREDENTIALS pCredentials,
IN PCRYPT_RETRIEVE_AUX_INFO pAuxInfo
)
{
BOOL fResult;
IObjectRetriever* por = NULL;
if ( !( dwRetrievalFlags & CRYPT_ASYNC_RETRIEVAL ) )
{
por = new CFileSynchronousRetriever;
}
if ( por == NULL )
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
fResult = por->RetrieveObjectByUrl(
pwszUrl,
pszObjectOid,
dwRetrievalFlags,
dwTimeout,
(LPVOID *)pObject,
ppfnFreeObject,
ppvFreeContext,
hAsyncRetrieve,
pCredentials,
NULL,
pAuxInfo
);
por->Release();
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Function: FileFreeEncodedObject
//
// Synopsis: free encoded object retrieved via FileRetrieveEncodedObject
//
//----------------------------------------------------------------------------
VOID WINAPI FileFreeEncodedObject (
IN LPCSTR pszObjectOid,
IN PCRYPT_BLOB_ARRAY pObject,
IN LPVOID pvFreeContext
)
{
BOOL fFreeBlobs = TRUE;
PFILE_BINDINGS pfb = (PFILE_BINDINGS)pvFreeContext;
//
// If no file bindings were given in the context then this
// must be a mapped file so we deal with it as such
//
if ( pfb != NULL )
{
fFreeBlobs = FALSE;
FileFreeBindings( pfb );
}
FileFreeCryptBlobArray( pObject, fFreeBlobs );
}
//+---------------------------------------------------------------------------
//
// Function: FileCancelAsyncRetrieval
//
// Synopsis: cancel asynchronous object retrieval
//
//----------------------------------------------------------------------------
BOOL WINAPI FileCancelAsyncRetrieval (
IN HCRYPTASYNC hAsyncRetrieve
)
{
SetLastError( (DWORD) E_NOTIMPL );
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Member: CFileSynchronousRetriever::CFileSynchronousRetriever, public
//
// Synopsis: Constructor
//
//----------------------------------------------------------------------------
CFileSynchronousRetriever::CFileSynchronousRetriever ()
{
m_cRefs = 1;
}
//+---------------------------------------------------------------------------
//
// Member: CFileSynchronousRetriever::~CFileSynchronousRetriever, public
//
// Synopsis: Destructor
//
//----------------------------------------------------------------------------
CFileSynchronousRetriever::~CFileSynchronousRetriever ()
{
}
//+---------------------------------------------------------------------------
//
// Member: CFileSynchronousRetriever::AddRef, public
//
// Synopsis: IRefCountedObject::AddRef
//
//----------------------------------------------------------------------------
VOID
CFileSynchronousRetriever::AddRef ()
{
InterlockedIncrement( (LONG *)&m_cRefs );
}
//+---------------------------------------------------------------------------
//
// Member: CFileSynchronousRetriever::Release, public
//
// Synopsis: IRefCountedObject::Release
//
//----------------------------------------------------------------------------
VOID
CFileSynchronousRetriever::Release ()
{
if ( InterlockedDecrement( (LONG *)&m_cRefs ) == 0 )
{
delete this;
}
}
//+---------------------------------------------------------------------------
//
// Member: CFileSynchronousRetriever::RetrieveObjectByUrl, public
//
// Synopsis: IObjectRetriever::RetrieveObjectByUrl
//
//----------------------------------------------------------------------------
BOOL
CFileSynchronousRetriever::RetrieveObjectByUrl (
LPCWSTR pwszUrl,
LPCSTR pszObjectOid,
DWORD dwRetrievalFlags,
DWORD dwTimeout,
LPVOID* ppvObject,
PFN_FREE_ENCODED_OBJECT_FUNC* ppfnFreeObject,
LPVOID* ppvFreeContext,
HCRYPTASYNC hAsyncRetrieve,
PCRYPT_CREDENTIALS pCredentials,
LPVOID pvVerify,
PCRYPT_RETRIEVE_AUX_INFO pAuxInfo
)
{
BOOL fResult = FALSE;
DWORD LastError = 0;
PFILE_BINDINGS pfb = NULL;
LPVOID pvFreeContext = NULL;
BOOL fIsUncUrl;
assert( hAsyncRetrieve == NULL );
fIsUncUrl = FileIsUncUrl( pwszUrl );
if ( ( dwRetrievalFlags & CRYPT_CACHE_ONLY_RETRIEVAL ) &&
( fIsUncUrl == TRUE ) )
{
return( SchemeRetrieveCachedCryptBlobArray(
pwszUrl,
dwRetrievalFlags,
(PCRYPT_BLOB_ARRAY)ppvObject,
ppfnFreeObject,
ppvFreeContext,
pAuxInfo
) );
}
fResult = FileGetBindings(
pwszUrl,
dwRetrievalFlags,
pCredentials,
&pfb,
pAuxInfo
);
if ( fResult == TRUE )
{
if ( pfb->fMapped == FALSE )
{
fResult = FileSendReceiveUrlRequest(
pfb,
(PCRYPT_BLOB_ARRAY)ppvObject
);
LastError = GetLastError();
FileFreeBindings( pfb );
}
else
{
fResult = FileConvertMappedBindings(
pfb,
(PCRYPT_BLOB_ARRAY)ppvObject
);
if ( fResult == TRUE )
{
pvFreeContext = (LPVOID)pfb;
}
else
{
LastError = GetLastError();
FileFreeBindings( pfb );
}
}
}
if ( fResult == TRUE )
{
if ( !( dwRetrievalFlags & CRYPT_DONT_CACHE_RESULT ) &&
( fIsUncUrl == TRUE ) )
{
fResult = SchemeCacheCryptBlobArray(
pwszUrl,
dwRetrievalFlags,
(PCRYPT_BLOB_ARRAY)ppvObject,
pAuxInfo
);
if ( fResult == FALSE )
{
FileFreeEncodedObject(
pszObjectOid,
(PCRYPT_BLOB_ARRAY)ppvObject,
pvFreeContext
);
}
}
else
{
SchemeRetrieveUncachedAuxInfo( pAuxInfo );
}
}
if ( fResult == TRUE )
{
*ppfnFreeObject = FileFreeEncodedObject;
*ppvFreeContext = pvFreeContext;
}
if ( LastError != 0 )
{
SetLastError( LastError );
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CInetSynchronousRetriever::CancelAsyncRetrieval, public
//
// Synopsis: IObjectRetriever::CancelAsyncRetrieval
//
//----------------------------------------------------------------------------
BOOL
CFileSynchronousRetriever::CancelAsyncRetrieval ()
{
SetLastError( (DWORD) E_NOTIMPL );
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Function: FileGetBindings
//
// Synopsis: get the file bindings
//
//----------------------------------------------------------------------------
BOOL
FileGetBindings (
LPCWSTR pwszUrl,
DWORD dwRetrievalFlags,
PCRYPT_CREDENTIALS pCredentials,
PFILE_BINDINGS* ppfb,
PCRYPT_RETRIEVE_AUX_INFO pAuxInfo
)
{
DWORD LastError;
LPWSTR pwszFile = (LPWSTR)pwszUrl;
HANDLE hFile;
HANDLE hFileMap;
LPVOID pvMap = NULL;
DWORD dwSize;
PFILE_BINDINGS pfb;
BOOL fResult;
WIN32_FILE_ATTRIBUTE_DATA FileAttr;
DWORD dwMaxUrlRetrievalByteCount = 0; // 0 => no max
if (pAuxInfo &&
offsetof(CRYPT_RETRIEVE_AUX_INFO, dwMaxUrlRetrievalByteCount) <
pAuxInfo->cbSize)
dwMaxUrlRetrievalByteCount = pAuxInfo->dwMaxUrlRetrievalByteCount;
if ( pCredentials != NULL )
{
SetLastError( (DWORD) E_NOTIMPL );
return( FALSE );
}
if ( wcsstr( pwszUrl, FILE_SCHEME_PLUSPLUS ) != NULL )
{
pwszFile += wcslen( FILE_SCHEME_PLUSPLUS );
}
fResult = GetFileAttributesExW(
pwszFile,
GetFileExInfoStandard,
&FileAttr
);
if (!fResult)
{
return(FALSE);
}
dwSize = FileAttr.nFileSizeLow;
if ((FileAttr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
(0 != FileAttr.nFileSizeHigh) || (0 == dwSize)
||
((0 != dwMaxUrlRetrievalByteCount) &&
(dwSize > dwMaxUrlRetrievalByteCount)))
{
I_CryptNetDebugErrorPrintfA(
"CRYPTNET.DLL --> Invalid File(%S):: Attributes: 0x%x Size: %d\n",
pwszFile, FileAttr.dwFileAttributes, FileAttr.nFileSizeLow);
SetLastError(ERROR_INVALID_DATA);
return FALSE;
}
pfb = new FILE_BINDINGS;
if ( pfb == NULL )
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
hFile = CreateFileW(
pwszFile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
if ( hFile == INVALID_HANDLE_VALUE )
{
delete pfb;
return( FALSE );
}
if ( dwSize <= FILE_MAPPING_THRESHOLD )
{
pfb->hFile = hFile;
pfb->dwSize = dwSize;
pfb->fMapped = FALSE;
pfb->hFileMap = NULL;
pfb->pvMap = NULL;
*ppfb = pfb;
return( TRUE );
}
hFileMap = CreateFileMappingA(
hFile,
NULL,
PAGE_READONLY,
0,
0,
NULL
);
if ( hFileMap != NULL )
{
pvMap = MapViewOfFile( hFileMap, FILE_MAP_READ, 0, 0, 0 );
}
if ( pvMap != NULL )
{
pfb->hFile = hFile;
pfb->dwSize = dwSize;
pfb->fMapped = TRUE;
pfb->hFileMap = hFileMap;
pfb->pvMap = pvMap;
*ppfb = pfb;
return( TRUE );
}
LastError = GetLastError();
if ( hFileMap != NULL )
{
CloseHandle( hFileMap );
}
if ( hFile != INVALID_HANDLE_VALUE )
{
CloseHandle( hFile );
}
delete pfb;
SetLastError( LastError );
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Function: FileFreeBindings
//
// Synopsis: free the file bindings
//
//----------------------------------------------------------------------------
VOID
FileFreeBindings (
PFILE_BINDINGS pfb
)
{
if ( pfb->fMapped == TRUE )
{
UnmapViewOfFile( pfb->pvMap );
CloseHandle( pfb->hFileMap );
}
CloseHandle( pfb->hFile );
delete pfb;
}
//+---------------------------------------------------------------------------
//
// Function: FileSendReceiveUrlRequest
//
// Synopsis: synchronously process the request for the file bits using
// Win32 File API. Note that this only works for non-mapped
// file bindings, for mapped file bindings use
// FileConvertMappedBindings
//
//----------------------------------------------------------------------------
BOOL
FileSendReceiveUrlRequest (
PFILE_BINDINGS pfb,
PCRYPT_BLOB_ARRAY pcba
)
{
BOOL fResult;
LPBYTE pb;
DWORD dwRead;
assert( pfb->fMapped == FALSE );
pb = CCryptBlobArray::AllocBlob( pfb->dwSize );
if ( pb == NULL )
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
fResult = ReadFile( pfb->hFile, pb, pfb->dwSize, &dwRead, NULL );
if ( fResult == TRUE )
{
CCryptBlobArray cba( 1, 1, fResult );
if ( dwRead == pfb->dwSize )
{
fResult = cba.AddBlob( pfb->dwSize, pb, FALSE );
}
else
{
SetLastError( (DWORD) E_FAIL );
fResult = FALSE;
}
if ( fResult == TRUE )
{
cba.GetArrayInNativeForm( pcba );
}
else
{
cba.FreeArray( FALSE );
}
}
if ( fResult == FALSE )
{
CCryptBlobArray::FreeBlob( pb );
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Function: FileConvertMappedBindings
//
// Synopsis: convert mapped bindings to a CRYPT_BLOB_ARRAY
//
//----------------------------------------------------------------------------
BOOL
FileConvertMappedBindings (
PFILE_BINDINGS pfb,
PCRYPT_BLOB_ARRAY pcba
)
{
BOOL fResult;
assert( pfb->fMapped == TRUE );
CCryptBlobArray cba( 1, 1, fResult );
if ( fResult == TRUE )
{
fResult = cba.AddBlob( pfb->dwSize, (LPBYTE)pfb->pvMap, FALSE );
}
if ( fResult == TRUE )
{
cba.GetArrayInNativeForm( pcba );
}
else
{
cba.FreeArray( FALSE );
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Function: FileFreeCryptBlobArray
//
// Synopsis: free the CRYPT_BLOB_ARRAY
//
//----------------------------------------------------------------------------
VOID
FileFreeCryptBlobArray (
PCRYPT_BLOB_ARRAY pcba,
BOOL fFreeBlobs
)
{
CCryptBlobArray cba( pcba, 0 );
cba.FreeArray( fFreeBlobs );
}
//+---------------------------------------------------------------------------
//
// Function: FileIsUncUrl
//
// Synopsis: is this a UNC path URL?
//
//----------------------------------------------------------------------------
BOOL
FileIsUncUrl (
LPCWSTR pwszUrl
)
{
DWORD cch = 0;
if ( wcsstr( pwszUrl, FILE_SCHEME_PLUSPLUS ) != NULL )
{
cch += wcslen( FILE_SCHEME_PLUSPLUS );
}
if ( ( pwszUrl[ cch ] == L'\\' ) && ( pwszUrl[ cch + 1 ] == L'\\' ) )
{
return( TRUE );
}
return( FALSE );
}