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.
 
 
 
 
 
 

185 lines
4.2 KiB

/******************************************************************************
*
* Copyright (c) 1999 Microsoft Corporation
*
* Module Name:
* hashlist.c
*
* Abstract:
* This file contains the implementation for hashed list required for
* file / extension lookups
*
* Revision History:
* Kanwaljit S Marok ( kmarok ) 05/17/99
* created
*
*****************************************************************************/
#include "precomp.h"
#include "hashlist.h"
#ifndef RING3
//
// linker commands
//
#ifdef ALLOC_PRAGMA
#pragma alloc_text( PAGE, MatchExtension )
#pragma alloc_text( PAGE, MatchEntry )
#endif // ALLOC_PRAGMA
#endif
//
// MatchEntry : Matched the given extension as PathElement and returns the
// entry type if it is found in the hash table.
//
BOOL
__inline
MatchEntry(
IN PBYTE pList, // Pointer to hash list
IN LPWSTR pStr, // Pointer to unicode path string
IN INT NumBytes, // Number of unichars in path string
OUT PINT pType ) // Pointer to variable returning ext type
{
INT iHash;
INT iNode;
ListEntry *pEntry;
BOOL fRet = FALSE;
iHash = HASHSTR(pList, pStr, (USHORT)NumBytes);
if( (iNode = HASH_BUCKET(pList, iHash)) != 0 )
{
pEntry = LIST_NODEPTR(pList, iNode);
while( pEntry )
{
if ( NumBytes == STR_BYTES(pEntry) &&
memcmp(pList + pEntry->m_dwData + sizeof(USHORT),
pStr,
NumBytes ) == 0
)
{
*pType = pEntry->m_dwType;
fRet = TRUE;
break;
}
if (pEntry->m_iNext == 0)
{
break;
}
pEntry = LIST_NODEPTR(pList, pEntry->m_iNext);
}
}
return fRet;
}
//
// MatchExtension: Extracts the extension and matches it against the
// hashed list
//
BOOL
__inline
MatchExtension(
IN PBYTE pList, // Pointer to hash list
IN PUNICODE_STRING pPath , // Pointer to unicode path
OUT PINT pType, // Pointer to node type
OUT PBOOL pbHasExt ) // Pointer to BOOL var returning ext result
{
BOOL fRet = FALSE;
INT i;
INT ExtLen = 0;
PWCHAR pExt = NULL;
UNICODE_STRING ext;
WCHAR pBuffer[ SR_MAX_EXTENSION_LENGTH+sizeof(WCHAR) ];
ASSERT(pList != NULL);
ASSERT(pPath != NULL);
ASSERT(pType != NULL);
ASSERT(pbHasExt != NULL);
ASSERT(pPath->Length >= sizeof(WCHAR));
*pbHasExt = FALSE;
//
// Find the start of an extension. We make sure that we don't find
// an extension that was on a data stream name.
//
for( i=(pPath->Length/sizeof(WCHAR))-1; i>=0; i--)
{
if (pPath->Buffer[i] == L'.')
{
if (pExt == NULL)
{
pExt = &pPath->Buffer[i+1];
}
}
else if (pPath->Buffer[i] == L':')
{
ExtLen = 0;
pExt = NULL;
}
else if (pPath->Buffer[i] == L'\\')
{
break;
}
else if (pExt == NULL)
{
ExtLen++;
}
if (ExtLen > SR_MAX_EXTENSION_CHARS)
{
break;
}
}
if( pExt && ExtLen > 0 )
{
*pbHasExt = TRUE;
//
// Create a unicode string for extension
//
ext.Buffer = pBuffer;
ext.Length = (USHORT)(ExtLen * sizeof(WCHAR));
ext.MaximumLength = sizeof(pBuffer);
memcpy( ext.Buffer,
pExt,
ext.Length );
ext.Buffer[ ExtLen ] = UNICODE_NULL;
//
// Convert to uppercase : Hope this works
//
RtlUpcaseUnicodeString( &ext, &ext, FALSE );
//
// Check extension list.
//
fRet = MatchEntry( pList,
ext.Buffer,
ext.Length,
pType);
}
return fRet;
}