⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.cpp

📁 本实例将通过ISAPI提供的功能实现访问控制过滤器(Autentication Filter)。可以设定最大访问用户的数量以及授权用户名和密码。
💻 CPP
字号:
/* 
DB.CPP 
    This module implements a simple user cache.  The cached users are kept
    in an LRU sorted list.  If there will be a large number of simultaneous
    users, then a sorted array would be more appropriate.
*/

#include "stdafx.h"
#include "AuthFilt.h"

/*
Routine Description:
    Initializes the cache module

Return Value:
    TRUE if initialized successfully, FALSE on error
*/
BOOL CAuthFilter::InitializeCache()
{
	if ( m_fCacheInitialized )
		return TRUE;

	InitializeCriticalSection( &m_csCacheLock );
	m_CacheListHead.Blink = m_CacheListHead.Flink = &m_CacheListHead;

	m_fCacheInitialized = TRUE;

	return TRUE;
}


/*
Routine Description:
    Checks to see if a user is in the cache and returns the user properties
    if found

Arguments:
    pszUserName - Case insensitive username to find
		pfFound     - Set to TRUE if the specified user was found
    pszPassword - Receives password for specified user if found
    pszNTUser   - Receives the NT Username to map this user to
    pszNTUserPassword - Receives the NT Password for m_achNTUser

Return Value:
    TRUE if no errors occurred.
*/
BOOL CAuthFilter::LookupUserInCache(const CHAR* pszUserName, BOOL* pfFound, CHAR* pszPassword, CHAR* pszNTUser, CHAR* pszNTUserPassword)
{
	LIST_ENTRY* pEntry;
	USER_INFO * pUser;
	DWORD       cPosition = 0;

	//  Search the cache for the specified user
	EnterCriticalSection( &m_csCacheLock );
	for ( pEntry = m_CacheListHead.Flink; pEntry != &m_CacheListHead; pEntry = pEntry->Flink)
	{
		pUser = CONTAINING_RECORD( pEntry, USER_INFO, ListEntry );
		if ( !stricmp( pszUserName, pUser->achUserName ))
			goto Found;

		cPosition++;
	}

	LeaveCriticalSection( &m_csCacheLock );

	//  Not Found
	*pfFound = FALSE;
	return TRUE;

Found:
	//  Copy out the user properties
	strcpy( pszPassword,       pUser->achPassword );
	strcpy( pszNTUser,         pUser->achNTUserName );
	strcpy( pszNTUserPassword, pUser->achNTUserPassword );

	//  Move this user entry to the front of the list as we're probably going
	//  to get subsequent requests for this user.  Note we only move it
	//  if it's not already near the front
	if ( cPosition > LIST_REORDER_THRESHOLD )
	{
		//  Remove from the old position...
		pEntry->Blink->Flink = pEntry->Flink;
		pEntry->Flink->Blink = pEntry->Blink;
		// ...and insert it at the beginning of the list
		pEntry->Blink = &m_CacheListHead;
		pEntry->Flink = m_CacheListHead.Flink;
		m_CacheListHead.Flink->Blink = pEntry;
		m_CacheListHead.Flink        = pEntry;
	}

	LeaveCriticalSection( &m_csCacheLock );

	*pfFound = TRUE;
	return TRUE;
}

/*
Routine Description:
    Adds the specified user to the cache

Arguments:
    pszUserName - Username to add
		pszPassword - Contains the external password for this user
    pszNTUser   - Contains the NT user name to use for this user
    pszNTUserPassword - Contains the password for NTUser

Return Value:
    TRUE if no errors occurred.
*/
BOOL CAuthFilter::AddUserToCache(const CHAR* pszUserName, const CHAR* pszPassword, const CHAR* pszNTUser, const CHAR* pszNTUserPassword)
{
	LIST_ENTRY* pEntry;
	USER_INFO*  pUser;

	//  Check our parameters before adding them to the cache
	if ( strlen( pszUserName ) > SF_MAX_USERNAME ||
			 strlen( pszPassword ) > SF_MAX_PASSWORD ||
			 strlen( pszNTUser   ) > SF_MAX_USERNAME ||
			 strlen( pszNTUserPassword ) > SF_MAX_PASSWORD )
	{
		SetLastError( ERROR_INVALID_PARAMETER );
		return FALSE;
	}

	//  Search the cache for the specified user to make sure there are no
	//  duplicates
	EnterCriticalSection( &m_csCacheLock );
	for ( pEntry  = m_CacheListHead.Flink; pEntry != &m_CacheListHead; pEntry = pEntry->Flink )
	{
		pUser = CONTAINING_RECORD( pEntry, USER_INFO, ListEntry );
		if ( !stricmp( pszUserName, pUser->achUserName ))
			goto Found;
	}

	//  Allocate a new cache item and put it at the head of the list
	pUser = (USER_INFO *) LocalAlloc( LPTR, sizeof( USER_INFO ));
	if ( !pUser )
	{
		LeaveCriticalSection( &m_csCacheLock );
		SetLastError( ERROR_NOT_ENOUGH_MEMORY );
		return FALSE;
	}
	pUser->ListEntry.Flink = m_CacheListHead.Flink;
	pUser->ListEntry.Blink = &m_CacheListHead;
	m_CacheListHead.Flink->Blink = &pUser->ListEntry;
	m_CacheListHead.Flink = &pUser->ListEntry;

Found:
	//  Set the various fields
	strcpy( pUser->achUserName,       pszUserName );
	strcpy( pUser->achPassword,       pszPassword );
	strcpy( pUser->achNTUserName,     pszNTUser );
	strcpy( pUser->achNTUserPassword, pszNTUserPassword );

	m_cCacheItems++;

	//  If there are too many cached users, remove the least recently
	//  used one now
	if ( m_cCacheItems > MAX_CACHED_USERS )
	{
		pEntry = m_CacheListHead.Blink;
		pEntry->Blink->Flink = &m_CacheListHead;
		m_CacheListHead.Blink  = pEntry->Blink;
		LocalFree( CONTAINING_RECORD( pEntry, USER_INFO, ListEntry ));
		m_cCacheItems--;
	}

	LeaveCriticalSection( &m_csCacheLock );

	return TRUE;
}

/*
Routine Description:
    Terminates the cache module and frees any allocated memory
*/
VOID CAuthFilter::TerminateCache()
{
	LIST_ENTRY* pEntry;
	LIST_ENTRY* pEntryNext;
	USER_INFO*  pUser;

	if ( !m_fCacheInitialized )
		return;

	EnterCriticalSection( &m_csCacheLock );

	// Free all of the cache entries
	for ( pEntry  = m_CacheListHead.Flink; pEntry != &m_CacheListHead; pEntry  = pEntryNext )
	{
		pUser = CONTAINING_RECORD( pEntry, USER_INFO, ListEntry );
		pEntryNext = pEntry->Flink;

		//  Remove this entry from the list and free it
		pEntry->Blink->Flink = pEntry->Flink;
		pEntry->Flink->Blink = pEntry->Blink;

		LocalFree( pUser );
	}

	m_cCacheItems = 0;
	LeaveCriticalSection( &m_csCacheLock );
	DeleteCriticalSection( &m_csCacheLock );
	m_fCacheInitialized = FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -