Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

476 lines
7.9 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
context.c
Abstract:
This module implements functions for creating and manipulating context
tables. Context tables are used in WinSock 2.0 for associating 32-bit
context values with socket handles.
Author:
Keith Moore (keithmo) 08-Nov-1995
Revision History:
--*/
#include "precomp.h"
//
// Private constants.
//
//
// INITIAL_ARRAY_ENTRIES is the initial number of lookup array entries
// in a newly created context table.
//
// ARRAY_GROWTH_DELTA is the growth delta used when growing the lookup
// array.
//
#define INITIAL_ARRAY_ENTRIES 256
#define ARRAY_GROWTH_DELTA 256
//
// TABLE_TO_LOCK() returns a pointer to a CONTEXT_TABLE's CRITICAL_SECTION
// object. This macro is only valid if the WAH_CONTEXT_FLAG_SERIALIZE bit
// is set in the Flags DWORD.
//
#define TABLE_TO_LOCK(t) ((LPCRITICAL_SECTION)((t) + 1))
//
// LOCK_TABLE locks a CONTEXT_TABLE, if the CONTEXT_TABLE is serialized.
//
// UNLOCK_TABLE unlocks a CONTEXT_TABLE, if the CONTEXT_TABLE is serialized.
//
#define LOCK_TABLE(t) \
if( (t)->Flags & WAH_CONTEXT_FLAG_SERIALIZE ) { \
EnterCriticalSection( TABLE_TO_LOCK(t) ); \
} else
#define UNLOCK_TABLE(t) \
if( (t)->Flags & WAH_CONTEXT_FLAG_SERIALIZE ) { \
LeaveCriticalSection( TABLE_TO_LOCK(t) ); \
} else
//
// Map a SOCKET to a KEY.
//
#ifdef CHICAGO
#define SOCKET_TO_KEY(s) ((DWORD)(s))
#else
#define SOCKET_TO_KEY(s) ((DWORD)(s) >> 2)
#endif
//
// Private types.
//
typedef struct _CONTEXT_TABLE {
DWORD Flags;
DWORD LookupArraySize;
LPVOID * LookupArray;
} CONTEXT_TABLE;
//
// Public functions.
//
DWORD
WINAPI
WahCreateContextTable(
LPCONTEXT_TABLE * Table,
DWORD Flags
)
/*++
Routine Description:
Creates a new context table.
Arguments:
Table - If successful, receives a pointer to the newly created context
table.
Flags - Flags to control the tables behaviour.
Return Value:
DWORD - NO_ERROR if successful, a Win32 error code if not.
--*/
{
DWORD newTableSize;
LPCONTEXT_TABLE newTable;
//
// Create the new context table.
//
newTableSize = sizeof(*newTable);
if( Flags & WAH_CONTEXT_FLAG_SERIALIZE ) {
newTableSize += sizeof(CRITICAL_SECTION);
}
newTable = ALLOC_MEM( newTableSize );
if( newTable != NULL ) {
//
// Initialize it.
//
if( Flags & WAH_CONTEXT_FLAG_SERIALIZE ) {
InitializeCriticalSection( TABLE_TO_LOCK( newTable ) );
}
newTable->Flags = Flags;
newTable->LookupArraySize = INITIAL_ARRAY_ENTRIES;
newTable->LookupArray = ALLOC_MEM( INITIAL_ARRAY_ENTRIES * sizeof(LPVOID) );
if( newTable->LookupArray != NULL ) {
//
// Success!
//
*Table = newTable;
return NO_ERROR;
}
//
// Allocated the CONTEXT_TABLE, but could not allocate the
// lookup array. Bummer.
//
FREE_MEM( newTable );
newTable = NULL;
}
*Table = newTable;
return ERROR_NOT_ENOUGH_MEMORY;
} // WahCreateContextTable
DWORD
WINAPI
WahDestroyContextTable(
LPCONTEXT_TABLE Table
)
/*++
Routine Description:
Destroys an existing context table.
Arguments:
Table - A pointer to the table to destroy.
Return Value:
DWORD - NO_ERROR if successful, a Win32 error code if not.
--*/
{
//
// Delete the context table's critical section if necessary.
//
if( Table->Flags & WAH_CONTEXT_FLAG_SERIALIZE ) {
DeleteCriticalSection( TABLE_TO_LOCK( Table ) );
}
//
// Free the resources.
//
FREE_MEM( Table->LookupArray );
FREE_MEM( Table );
//
// Success!
//
return NO_ERROR;
} // WahDestroyContextTable
DWORD
WINAPI
WahSetContext(
LPCONTEXT_TABLE Table,
SOCKET Socket,
LPVOID Context
)
/*++
Routine Description:
Associates the given context with the given key.
Arguments:
Table - The table to contain the new context.
Socket - The key to index the new context.
Context - The new context.
Return Value:
DWORD - NO_ERROR if successful, a Win32 error code if not.
--*/
{
DWORD newLookupArraySize;
LPVOID * newLookupArray;
DWORD key = SOCKET_TO_KEY( Socket );
//
// Acquire the lock protecting the context table.
//
LOCK_TABLE( Table );
//
// Determine if we can do this without growing the lookup array.
//
if( Table->LookupArraySize > key ) {
Table->LookupArray[key] = Context;
UNLOCK_TABLE( Table );
return NO_ERROR;
}
//
// We'll need to grow the lookup array first.
//
newLookupArraySize = Table->LookupArraySize +
ARRAY_GROWTH_DELTA *
( ( ( key - Table->LookupArraySize ) / ARRAY_GROWTH_DELTA ) + 1 );
newLookupArray = REALLOC_MEM(
Table->LookupArray,
newLookupArraySize * sizeof(LPVOID)
);
if( newLookupArray != NULL ) {
Table->LookupArray = newLookupArray;
Table->LookupArraySize = newLookupArraySize;
Table->LookupArray[key] = Context;
UNLOCK_TABLE( Table );
return NO_ERROR;
}
//
// Error growing the lookup array.
//
UNLOCK_TABLE( Table );
return ERROR_NOT_ENOUGH_MEMORY;
} // WahSetContext
DWORD
WINAPI
WahGetContext(
LPCONTEXT_TABLE Table,
SOCKET Socket,
LPVOID * Context
)
/*++
Routine Description:
Retrieves the context associated with the given key.
Arguments:
Table - The table to use for the context lookup.
Socket - The key to lookup.
Context - If successful, receives the context value.
Return Value:
DWORD - NO_ERROR if successful, a Win32 error code if not.
--*/
{
DWORD key = SOCKET_TO_KEY( Socket );
//
// Acquire the lock protecting the context table.
//
LOCK_TABLE( Table );
//
// Validate the key before indexing into the lookup array.
//
if( key < Table->LookupArraySize ) {
*Context = Table->LookupArray[key];
if( *Context != NULL ) {
UNLOCK_TABLE( Table );
return NO_ERROR;
}
}
//
// Invalid key.
//
UNLOCK_TABLE( Table );
return ERROR_INVALID_PARAMETER;
} // WahGetContext
DWORD
WINAPI
WahRemoveContextEx(
LPCONTEXT_TABLE Table,
SOCKET Socket,
LPVOID Context
)
/*++
Routine Description:
Removes a context association from the given table.
Arguments:
Table - The table to remove the context from.
Socket - The key to remove.
Context - the context that should be in the table
Return Value:
DWORD - NO_ERROR if successful, a Win32 error code if not.
--*/
{
DWORD key = SOCKET_TO_KEY( Socket );
DWORD err;
//
// Acquire the lock protecting the context table.
//
LOCK_TABLE( Table );
//
// Validate the key before indexing into the lookup array.
//
if( key < Table->LookupArraySize ) {
if( !Context || ( Table->LookupArray[key] == Context ) ) {
Table->LookupArray[key] = NULL;
err = NO_ERROR;
} else {
if( Table->LookupArray[key] ) {
err = ERROR_FILE_EXISTS;
} else {
err = ERROR_DEV_NOT_EXIST;
}
}
} else {
err = ERROR_INVALID_PARAMETER;
}
//
// Cleanup and return
//
UNLOCK_TABLE( Table );
return err;
} // WahRemoveContextEx
DWORD
WINAPI
WahRemoveContext(
LPCONTEXT_TABLE Table,
SOCKET Socket
)
{
return WahRemoveContextEx( Table, Socket, NULL );
} // WahRemoveContext