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
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;
|
|
}
|
|
|