mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
- Add ws2help from alex-network-branch
svn path=/trunk/; revision=42115
This commit is contained in:
parent
fd8fa4a64c
commit
c2018d5633
11 changed files with 1739 additions and 0 deletions
152
reactos/dll/win32/ws2help_new/apc.c
Normal file
152
reactos/dll/win32/ws2help_new/apc.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 DLL
|
||||
* FILE: include/ws2_32.h
|
||||
* PURPOSE: WinSock 2 DLL header
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
/* DATA **********************************************************************/
|
||||
|
||||
#define APCH (HANDLE)'SOR '
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahOpenApcHelper(OUT PHANDLE ApcHelperHandle)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Validate handle */
|
||||
if (!ApcHelperHandle) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
/*
|
||||
* Return a bogus handle ("ROS")
|
||||
* Historical note:(MS sends "CKM", which probably stands for "Keith Moore"
|
||||
* (KM), one of the core architects of Winsock 2.2 from Microsoft.
|
||||
*/
|
||||
*ApcHelperHandle = APCH;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseApcHelper(IN HANDLE ApcHelperHandle)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Validate handle */
|
||||
if (ApcHelperHandle != APCH) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
/* return */
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseThread(IN HANDLE ApcHelperHandle,
|
||||
IN LPWSATHREADID ThreadId)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Validate handles */
|
||||
if ((ApcHelperHandle != APCH) || (!ThreadId) || (!ThreadId->ThreadHandle))
|
||||
{
|
||||
/* Invalid helper/thread handles */
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Close the thread handle */
|
||||
if (CloseHandle(ThreadId->ThreadHandle))
|
||||
{
|
||||
/* Clear the sturcture */
|
||||
ThreadId->ThreadHandle = NULL;
|
||||
ThreadId->Reserved = 0;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/* return */
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
WahQueueUserApc(IN HANDLE ApcHelperHandle,
|
||||
IN LPWSATHREADID ThreadId,
|
||||
IN LPWSAUSERAPC ApcRoutine,
|
||||
IN PVOID ApcContext OPTIONAL)
|
||||
{
|
||||
/* Validate params */
|
||||
if ((ApcHelperHandle != APCH) ||
|
||||
(!ThreadId) ||
|
||||
(!ThreadId->ThreadHandle) ||
|
||||
(!ApcRoutine))
|
||||
{
|
||||
/* Invalid parameters */
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Queue the APC */
|
||||
if (QueueUserAPC(ApcRoutine, ThreadId->ThreadHandle, (ULONG_PTR)ApcContext))
|
||||
{
|
||||
/* Return success */
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/* Fail */
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahOpenCurrentThread(IN HANDLE ApcHelperHandle,
|
||||
OUT LPWSATHREADID ThreadId)
|
||||
{
|
||||
HANDLE ProcessHandle, ThreadHandle;
|
||||
|
||||
/* Validate params */
|
||||
if ((ApcHelperHandle != APCH) || (!ThreadId))
|
||||
{
|
||||
/* Invalid parameters */
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Get the process/thread handles */
|
||||
ProcessHandle = GetCurrentProcess();
|
||||
ThreadHandle = GetCurrentThread();
|
||||
|
||||
/* Duplicate the handle */
|
||||
if (DuplicateHandle(ProcessHandle,
|
||||
ThreadHandle,
|
||||
ProcessHandle,
|
||||
&ThreadId->ThreadHandle,
|
||||
0,
|
||||
FALSE,
|
||||
DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
/* Save the thread handle and return */
|
||||
ThreadId->Reserved = (DWORD_PTR)ThreadHandle;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/* Fail */
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
/* EOF */
|
601
reactos/dll/win32/ws2help_new/context.c
Normal file
601
reactos/dll/win32/ws2help_new/context.c
Normal file
|
@ -0,0 +1,601 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 DLL
|
||||
* FILE: include/ws2_32.h
|
||||
* PURPOSE: WinSock 2 DLL header
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
/* DATA **********************************************************************/
|
||||
|
||||
CRITICAL_SECTION WshHandleTableLock;
|
||||
HANDLE ghWriterEvent;
|
||||
DWORD gdwSpinCount = 0;
|
||||
DWORD gHandleToIndexMask;
|
||||
|
||||
CONST DWORD SockPrimes[] =
|
||||
{
|
||||
31, 61, 127, 257, 521, 1031, 2053,
|
||||
4099, 8191, 16381, 32749, 65537, 131071, 261983,
|
||||
-1
|
||||
};
|
||||
|
||||
typedef volatile LONG VLONG;
|
||||
typedef VLONG *PVLONG;
|
||||
|
||||
/* DEFINES *******************************************************************/
|
||||
|
||||
/* Yes, we "abuse" the lower bits */
|
||||
#define WSH_SEARCH_TABLE_FROM_HANDLE(h, t) \
|
||||
(&t->SearchTables[(((ULONG_PTR)h >> 2) & t->Mask)])
|
||||
|
||||
#define WSH_HASH_FROM_HANDLE(h, hs) \
|
||||
(hs->Handles[((ULONG_PTR)h % hs->Size)])
|
||||
|
||||
#define AcquireWriteLock(t) \
|
||||
EnterCriticalSection(&t->Lock);
|
||||
|
||||
#define ReleaseWriteLock(t) \
|
||||
LeaveCriticalSection(&t->Lock);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
static __inline
|
||||
AcquireReadLock(IN PWAH_SEARCH_TABLE Table,
|
||||
IN PVLONG *Count)
|
||||
{
|
||||
LONG OldCount;
|
||||
|
||||
/* Start acquire loop */
|
||||
do
|
||||
{
|
||||
/* Write and save count value */
|
||||
*Count = Table->CurrentCount;
|
||||
OldCount = **Count;
|
||||
|
||||
/* Check if it's valid and try to increment it */
|
||||
if ((OldCount > 0) && (InterlockedCompareExchange(*Count,
|
||||
OldCount + 1,
|
||||
OldCount) == OldCount))
|
||||
{
|
||||
/* Everything went OK */
|
||||
break;
|
||||
}
|
||||
} while (TRUE);
|
||||
}
|
||||
|
||||
VOID
|
||||
static __inline
|
||||
ReleaseReadLock(IN PWAH_SEARCH_TABLE Table,
|
||||
IN PVLONG Count)
|
||||
{
|
||||
/* Decrement the count. If we went below 0, someone is waiting... */
|
||||
if (InterlockedDecrement(Count) < 0)
|
||||
{
|
||||
/* We use pulse since this is a shared event */
|
||||
PulseEvent(ghWriterEvent);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
DoWaitForReaders(IN PWAH_SEARCH_TABLE Table,
|
||||
IN PVLONG Counter)
|
||||
{
|
||||
HANDLE EventHandle;
|
||||
|
||||
/* Do a context switch */
|
||||
SwitchToThread();
|
||||
|
||||
/* Check if the counter is above one */
|
||||
if (*Counter > 0)
|
||||
{
|
||||
/*
|
||||
* This shouldn't happen unless priorities are messed up. Do a wait so
|
||||
* that the threads with lower priority will get their chance now.
|
||||
*/
|
||||
if (!ghWriterEvent)
|
||||
{
|
||||
/* We don't even have an event! Allocate one manually... */
|
||||
EventHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (EventHandle)
|
||||
{
|
||||
/* Save the event handle atomically */
|
||||
if ((InterlockedCompareExchangePointer((PVOID*)&ghWriterEvent,
|
||||
EventHandle,
|
||||
NULL)))
|
||||
{
|
||||
/* Someone beat us to it, close ours */
|
||||
CloseHandle(EventHandle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Things couldn't get worse for us. Do a last-resort hack */
|
||||
while (*Counter > 0) Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Our event is ready. Tell the others to signal us by making sure
|
||||
* that the last counter will be -1, notifying the last thread of our
|
||||
* request.
|
||||
*/
|
||||
if (InterlockedDecrement(Counter) >= 0)
|
||||
{
|
||||
/* Keep looping */
|
||||
do
|
||||
{
|
||||
/* Wait in tiny bursts, so we can catch the PulseEvent */
|
||||
WaitForSingleObject(ghWriterEvent, 10);
|
||||
} while (*Counter >= 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
static __inline
|
||||
TryWaitForReaders(IN PWAH_SEARCH_TABLE Table)
|
||||
{
|
||||
PVLONG OldCount = Table->CurrentCount;
|
||||
LONG SpinCount;
|
||||
|
||||
/* See which counter is being used */
|
||||
if (OldCount == &Table->Count1)
|
||||
{
|
||||
/* Use counter 2 now */
|
||||
Table->Count2 = 1;
|
||||
Table->CurrentCount = &Table->Count2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use counter 1 now */
|
||||
Table->Count1 = 1;
|
||||
Table->CurrentCount = &Table->Count1;
|
||||
}
|
||||
|
||||
/* Decrease the old count to block new readers */
|
||||
if (InterlockedDecrement(OldCount) > 0)
|
||||
{
|
||||
/* On an MP machine, spin a bit first */
|
||||
if (Table->SpinCount)
|
||||
{
|
||||
/* Get the spincount and loop it */
|
||||
SpinCount = Table->SpinCount;
|
||||
while (*OldCount > 0)
|
||||
{
|
||||
/* Check if the spin failed */
|
||||
if (--SpinCount <= 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check one last time if someone is still active */
|
||||
if (*OldCount > 0)
|
||||
{
|
||||
/* Yep, we'll have to do a blocking (slow) wait */
|
||||
DoWaitForReaders(Table, OldCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCreateHandleContextTable(OUT PWAH_HANDLE_TABLE *Table)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
PWAH_HANDLE_TABLE LocalTable;
|
||||
DWORD i;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Assume NULL */
|
||||
*Table = NULL;
|
||||
|
||||
/* Allocate enough tables */
|
||||
LocalTable = HeapAlloc(GlobalHeap,
|
||||
0,
|
||||
FIELD_OFFSET(WSH_HANDLE_TABLE,
|
||||
SearchTables[gHandleToIndexMask + 1]));
|
||||
|
||||
/* Make sure it was allocated */
|
||||
if (!LocalTable) return WSA_NOT_ENOUGH_MEMORY;
|
||||
|
||||
/* Set the mask for the table */
|
||||
LocalTable->Mask = gHandleToIndexMask;
|
||||
|
||||
/* Now initialize every table */
|
||||
for (i = 0; i <= gHandleToIndexMask; i++)
|
||||
{
|
||||
/* No hash table yet */
|
||||
LocalTable->SearchTables[i].HashTable = NULL;
|
||||
|
||||
/* Set the current count */
|
||||
LocalTable->SearchTables[i].CurrentCount = &LocalTable->SearchTables[i].Count1;
|
||||
|
||||
/* Initialize the counts */
|
||||
LocalTable->SearchTables[i].Count1 = 1;
|
||||
LocalTable->SearchTables[i].Count2 = 0;
|
||||
|
||||
/* Set expanding state and spin count */
|
||||
LocalTable->SearchTables[i].Expanding = FALSE;
|
||||
LocalTable->SearchTables[i].SpinCount = gdwSpinCount;
|
||||
|
||||
/* Initialize the lock */
|
||||
(VOID)InitializeCriticalSectionAndSpinCount(&LocalTable->
|
||||
SearchTables[i].Lock,
|
||||
gdwSpinCount);
|
||||
}
|
||||
|
||||
/* Return pointer */
|
||||
*Table = LocalTable;
|
||||
|
||||
/* Return success */
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahDestroyHandleContextTable(IN PWAH_HANDLE_TABLE Table)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
/* Make sure the table is valid */
|
||||
if (!Table)
|
||||
{
|
||||
/* No valid table */
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Loop each search table */
|
||||
for (i = 0; i <= Table->Mask; i++)
|
||||
{
|
||||
/* Check if there's a table here */
|
||||
if (Table->SearchTables[i].HashTable)
|
||||
{
|
||||
/* Free it */
|
||||
HeapFree(GlobalHeap, 0, Table->SearchTables[i].HashTable);
|
||||
}
|
||||
|
||||
/* Delete the lock */
|
||||
DeleteCriticalSection(&Table->SearchTables[i].Lock);
|
||||
}
|
||||
|
||||
/* Delete the table */
|
||||
HeapFree(GlobalHeap, 0, Table);
|
||||
|
||||
/* Return success */
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
WahEnumerateHandleContexts(IN PWAH_HANDLE_TABLE Table,
|
||||
IN PWAH_HANDLE_ENUMERATE_PROC Callback,
|
||||
IN PVOID Context)
|
||||
{
|
||||
DWORD i, j;
|
||||
PWAH_SEARCH_TABLE SearchTable;
|
||||
PWAH_HASH_TABLE HashTable;
|
||||
PWAH_HANDLE Handle;
|
||||
BOOL GoOn = TRUE;
|
||||
|
||||
/* Loop the table */
|
||||
for (i = 0; i <= Table->Mask; i++)
|
||||
{
|
||||
/* Get the Search table */
|
||||
SearchTable = &Table->SearchTables[i];
|
||||
|
||||
/* Lock it */
|
||||
AcquireWriteLock(SearchTable);
|
||||
|
||||
/* Mark us as expanding and wait for everyone */
|
||||
SearchTable->Expanding = TRUE;
|
||||
TryWaitForReaders(SearchTable);
|
||||
|
||||
/* Get the hash table */
|
||||
HashTable = SearchTable->HashTable;
|
||||
|
||||
/* Make sure it exists */
|
||||
if (HashTable)
|
||||
{
|
||||
/* Loop every handle in it */
|
||||
for (j = 0; j < HashTable->Size; j++)
|
||||
{
|
||||
/* Get this handle */
|
||||
Handle = HashTable->Handles[j];
|
||||
if (!Handle) continue;
|
||||
|
||||
/* Call the callback proc */
|
||||
GoOn = Callback(Context, Handle);
|
||||
if (!GoOn) break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the expansion bit and release the lock */
|
||||
SearchTable->Expanding = FALSE;
|
||||
ReleaseWriteLock(SearchTable);
|
||||
|
||||
/* Check again if we should leave */
|
||||
if (!GoOn) break;
|
||||
}
|
||||
|
||||
/* return */
|
||||
return GoOn;
|
||||
}
|
||||
|
||||
PWAH_HANDLE
|
||||
WINAPI
|
||||
WahInsertHandleContext(IN PWAH_HANDLE_TABLE Table,
|
||||
IN PWAH_HANDLE Handle)
|
||||
{
|
||||
PWAH_HANDLE *HashHandle, OldHandle;
|
||||
PVLONG Count;
|
||||
PWAH_HASH_TABLE HashTable, NewHashTable;
|
||||
DWORD HandleCount, i;
|
||||
PWAH_SEARCH_TABLE SearchTable;
|
||||
|
||||
/* Get the current Search Table */
|
||||
SearchTable = WSH_SEARCH_TABLE_FROM_HANDLE(Handle->Handle, Table);
|
||||
|
||||
/* Start loop */
|
||||
do
|
||||
{
|
||||
/* Get reader lock */
|
||||
AcquireReadLock(SearchTable, &Count);
|
||||
|
||||
/* Get the hash table */
|
||||
HashTable = SearchTable->HashTable;
|
||||
|
||||
/* Make sure we are not expanding, and that the table is there */
|
||||
if (!(SearchTable->Expanding) && (HashTable))
|
||||
{
|
||||
/* Get the hash handle */
|
||||
HashHandle = &WSH_HASH_FROM_HANDLE(Handle->Handle, HashTable);
|
||||
|
||||
/* Do the insert */
|
||||
if (InterlockedCompareExchangePointer((PVOID*)HashHandle,
|
||||
Handle,
|
||||
NULL) == NULL)
|
||||
{
|
||||
/* Success, release the reader lock */
|
||||
ReleaseReadLock(SearchTable, Count);
|
||||
|
||||
/* Save old handle */
|
||||
OldHandle = Handle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the read lock since we're done with it now */
|
||||
ReleaseReadLock(SearchTable, Count);
|
||||
|
||||
/* We need the writer lock to expand/create the table */
|
||||
AcquireWriteLock(SearchTable);
|
||||
|
||||
/* Mark the table in use */
|
||||
SearchTable->Expanding = TRUE;
|
||||
|
||||
/* Wait for all the readers to finish */
|
||||
TryWaitForReaders(SearchTable);
|
||||
|
||||
/* Start loop */
|
||||
do
|
||||
{
|
||||
/* Get the hash table again */
|
||||
HashTable = SearchTable->HashTable;
|
||||
|
||||
/* Check if exists now */
|
||||
if (HashTable)
|
||||
{
|
||||
/* It does! Do what we wanted to do earlier. Get the hash... */
|
||||
HashHandle = &WSH_HASH_FROM_HANDLE(Handle->Handle, HashTable);
|
||||
|
||||
/* Check if it doesn't exist */
|
||||
if (!(*HashHandle))
|
||||
{
|
||||
/* Write it (no need for interlock, we have the RW lock) */
|
||||
OldHandle = Handle;
|
||||
*HashHandle = Handle;
|
||||
break;
|
||||
}
|
||||
else if ((*HashHandle)->Handle == Handle->Handle)
|
||||
{
|
||||
/* Handle matches, write it (see comment above) */
|
||||
OldHandle = *HashHandle;
|
||||
*HashHandle = Handle;
|
||||
break;
|
||||
}
|
||||
|
||||
/* No go, we need to expand the table. Remember the size now */
|
||||
HandleCount = HashTable->Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Table is empty, we have to create it */
|
||||
HandleCount = 0;
|
||||
}
|
||||
|
||||
ExpandTable:
|
||||
/* Find a free prime */
|
||||
for (i = 0; HandleCount >= SockPrimes[i]; i++);
|
||||
|
||||
/* Check if we found one */
|
||||
if (SockPrimes[i] != 0xFFFFFFFF)
|
||||
{
|
||||
/* Use the prime */
|
||||
HandleCount = SockPrimes[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No primes left. Table is quite large, so simply double it */
|
||||
HandleCount *= 2;
|
||||
}
|
||||
|
||||
/* Allocate the table */
|
||||
NewHashTable = HeapAlloc(GlobalHeap,
|
||||
0,
|
||||
FIELD_OFFSET(WSH_HASH_TABLE,
|
||||
Handles[HandleCount]));
|
||||
|
||||
/* Hopefully we have one now */
|
||||
if (NewHashTable)
|
||||
{
|
||||
/* Set its size */
|
||||
NewHashTable->Size = HandleCount;
|
||||
|
||||
/* Initialize it */
|
||||
RtlZeroMemory(NewHashTable->Handles, HandleCount * sizeof(PVOID));
|
||||
|
||||
/* Insert us first */
|
||||
WSH_HASH_FROM_HANDLE(Handle->Handle, NewHashTable) = Handle;
|
||||
|
||||
/* Now check if our old table had entries in it */
|
||||
if (HashTable)
|
||||
{
|
||||
/* We need to move them */
|
||||
for (i = 0; i < HashTable->Size; i++)
|
||||
{
|
||||
/* Make sure the hash handle exists */
|
||||
if (HashTable->Handles[i])
|
||||
{
|
||||
/* Get it */
|
||||
HashHandle = &WSH_HASH_FROM_HANDLE(HashTable->
|
||||
Handles[i]->Handle,
|
||||
NewHashTable);
|
||||
|
||||
/* Check if it has a value */
|
||||
if (!(*HashHandle))
|
||||
{
|
||||
/* It's empty, so just write the handle */
|
||||
*HashHandle = HashTable->Handles[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not empty :/... that implies a collision */
|
||||
HeapFree(GlobalHeap, 0, NewHashTable);
|
||||
goto ExpandTable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the new hash table */
|
||||
SearchTable->HashTable = NewHashTable;
|
||||
|
||||
/* Wait for everyone to be done with it, then free it */
|
||||
TryWaitForReaders(SearchTable);
|
||||
HeapFree(GlobalHeap, 0, HashTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It was empty, nothing to worry about */
|
||||
SearchTable->HashTable = NewHashTable;
|
||||
}
|
||||
|
||||
/* Save the old handle */
|
||||
OldHandle = Handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There was no old handle */
|
||||
OldHandle = Handle;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
/* Mark us as free, and release the write lock */
|
||||
SearchTable->Expanding = FALSE;
|
||||
ReleaseWriteLock(SearchTable);
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
/* Return the old handle */
|
||||
return OldHandle;
|
||||
}
|
||||
|
||||
PWAH_HANDLE
|
||||
WINAPI
|
||||
WahReferenceContextByHandle(IN PWAH_HANDLE_TABLE Table,
|
||||
IN HANDLE Handle)
|
||||
{
|
||||
PWAH_HANDLE HashHandle;
|
||||
PWAH_SEARCH_TABLE SearchTable;
|
||||
PWAH_HASH_TABLE HashTable;
|
||||
PVLONG Count;
|
||||
|
||||
/* Get the current Search Table */
|
||||
SearchTable = WSH_SEARCH_TABLE_FROM_HANDLE(Handle, Table);
|
||||
|
||||
/* Lock it */
|
||||
AcquireReadLock(SearchTable, &Count);
|
||||
|
||||
/* Get the hash table and handle */
|
||||
HashTable = SearchTable->HashTable;
|
||||
|
||||
/* Check if it's valid, and if it's the one we want */
|
||||
if ((HashTable) &&
|
||||
(HashHandle = WSH_HASH_FROM_HANDLE(Handle, HashTable)) &&
|
||||
(HashHandle->Handle == Handle))
|
||||
{
|
||||
/* Reference the handle */
|
||||
InterlockedIncrement(&HashHandle->RefCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid handle */
|
||||
HashHandle = NULL;
|
||||
}
|
||||
|
||||
/* Release the lock */
|
||||
ReleaseReadLock(SearchTable, Count);
|
||||
|
||||
/* Return */
|
||||
return HashHandle;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahRemoveHandleContext(IN PWAH_HANDLE_TABLE Table,
|
||||
IN PWAH_HANDLE Handle)
|
||||
{
|
||||
PWAH_HANDLE *HashHandle;
|
||||
PWAH_SEARCH_TABLE SearchTable;
|
||||
PWAH_HASH_TABLE HashTable;
|
||||
DWORD ErrorCode = ERROR_SUCCESS;
|
||||
|
||||
/* Get the current Search Table */
|
||||
SearchTable = WSH_SEARCH_TABLE_FROM_HANDLE(Handle->Handle, Table);
|
||||
|
||||
/* Lock it */
|
||||
AcquireWriteLock(SearchTable);
|
||||
|
||||
/* Get the hash table and handle */
|
||||
HashTable = SearchTable->HashTable;
|
||||
HashHandle = &WSH_HASH_FROM_HANDLE(Handle->Handle, HashTable);
|
||||
|
||||
/* Make sure we have a handle, and write the new pointer */
|
||||
if (HashHandle && (InterlockedCompareExchangePointer((PVOID*)HashHandle,
|
||||
NULL,
|
||||
Handle) == Handle))
|
||||
{
|
||||
/* Wait for everyone to be done with it */
|
||||
TryWaitForReaders(SearchTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid handle */
|
||||
ErrorCode = ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Release the lock */
|
||||
ReleaseWriteLock(SearchTable);
|
||||
|
||||
/* Return */
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
/* EOF */
|
170
reactos/dll/win32/ws2help_new/dllmain.c
Normal file
170
reactos/dll/win32/ws2help_new/dllmain.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 DLL
|
||||
* FILE: include/ws2_32.h
|
||||
* PURPOSE: WinSock 2 DLL header
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
/* DATA **********************************************************************/
|
||||
|
||||
HANDLE GlobalHeap;
|
||||
BOOL Ws2helpInitialized = FALSE;
|
||||
CRITICAL_SECTION StartupSyncronization;
|
||||
HINSTANCE LibraryHdl;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
NewCtxInit(VOID)
|
||||
{
|
||||
NT_PRODUCT_TYPE ProductType = NtProductWinNt;
|
||||
SYSTEM_INFO SystemInfo;
|
||||
DWORD NumHandleBuckets;
|
||||
HKEY KeyHandle;
|
||||
DWORD RegSize = sizeof(DWORD);
|
||||
DWORD RegType;
|
||||
DWORD Mask;
|
||||
|
||||
/* Try to figure out if this is a workstation or server install */
|
||||
RtlGetNtProductType(&ProductType);
|
||||
|
||||
/* Get the system info */
|
||||
GetSystemInfo(&SystemInfo);
|
||||
|
||||
/* If this is an MP machine, set the default spinlock */
|
||||
if (SystemInfo.dwNumberOfProcessors > 1) gdwSpinCount = 2000;
|
||||
|
||||
/* Figure how many "Handle Buckets" we'll use. Start with the default */
|
||||
NumHandleBuckets = ProductType == NtProductWinNt ? 8 : 32;
|
||||
|
||||
/* Open the registry settings */
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||
"System\\CurrentControlSet\\Services\\Winsock2\\Parameters",
|
||||
0,
|
||||
KEY_QUERY_VALUE,
|
||||
&KeyHandle) == ERROR_SUCCESS)
|
||||
{
|
||||
/* Query the key */
|
||||
RegQueryValueEx(KeyHandle,
|
||||
"Ws2_32NumHandleBuckets",
|
||||
0,
|
||||
&RegType,
|
||||
(LPBYTE)&NumHandleBuckets,
|
||||
&RegSize);
|
||||
|
||||
/* Are we on MP? */
|
||||
if (SystemInfo.dwNumberOfProcessors > 1)
|
||||
{
|
||||
/* Also check for a custom spinlock setting */
|
||||
RegQueryValueEx(KeyHandle,
|
||||
"Ws2_32SpinCount",
|
||||
0,
|
||||
&RegType,
|
||||
(LPBYTE)&gdwSpinCount,
|
||||
&RegSize);
|
||||
}
|
||||
|
||||
/* Close the key, we're done */
|
||||
RegCloseKey(KeyHandle);
|
||||
}
|
||||
|
||||
/* Now get the bucket count and normalize it to be log2 and within 256 */
|
||||
for (Mask = 256; !(Mask & NumHandleBuckets); Mask >>= 1);
|
||||
NumHandleBuckets = Mask;
|
||||
|
||||
/* Normalize it again, to be within OS parameters */
|
||||
if (ProductType == NtProductWinNt)
|
||||
{
|
||||
/* Is it within norms for non-server editions? */
|
||||
if (NumHandleBuckets > 32) NumHandleBuckets = 32;
|
||||
else if (NumHandleBuckets < 8) NumHandleBuckets = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Is it within norms for server editions? */
|
||||
if (NumHandleBuckets > 256) NumHandleBuckets = 256;
|
||||
else if (NumHandleBuckets < 32) NumHandleBuckets = 32;
|
||||
}
|
||||
|
||||
/* Normalize the spincount */
|
||||
if (gdwSpinCount > 8000) gdwSpinCount = 8000;
|
||||
|
||||
/* Set the final mask */
|
||||
gHandleToIndexMask = NumHandleBuckets -1;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
Ws2helpInitialize(VOID)
|
||||
{
|
||||
/* Enter the startup CS */
|
||||
EnterCriticalSection(&StartupSyncronization);
|
||||
|
||||
/* Check again for init */
|
||||
if (!Ws2helpInitialized)
|
||||
{
|
||||
/* Initialize us */
|
||||
NewCtxInit();
|
||||
Ws2helpInitialized = TRUE;
|
||||
}
|
||||
|
||||
/* Leave the CS and return */
|
||||
LeaveCriticalSection(&StartupSyncronization);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL
|
||||
APIENTRY
|
||||
DllMain(HANDLE hModule,
|
||||
DWORD dwReason,
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
|
||||
/* Save our handle */
|
||||
LibraryHdl = hModule;
|
||||
|
||||
/* Improve Performance */
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
|
||||
/* Initialize startup CS */
|
||||
InitializeCriticalSection(&StartupSyncronization);
|
||||
|
||||
/* Get Global Heap */
|
||||
GlobalHeap = GetProcessHeap();
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
|
||||
/* Make sure we loaded */
|
||||
if (!LibraryHdl) break;
|
||||
|
||||
/* Check if we are cleaning up */
|
||||
if (lpReserved)
|
||||
{
|
||||
/* Free the security descriptor */
|
||||
if (pSDPipe) HeapFree(GlobalHeap, 0, pSDPipe);
|
||||
|
||||
/* Close the event */
|
||||
if (ghWriterEvent) CloseHandle(ghWriterEvent);
|
||||
|
||||
/* Delete the startup CS */
|
||||
DeleteCriticalSection(&StartupSyncronization);
|
||||
Ws2helpInitialized = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
447
reactos/dll/win32/ws2help_new/handle.c
Normal file
447
reactos/dll/win32/ws2help_new/handle.c
Normal file
|
@ -0,0 +1,447 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 DLL
|
||||
* FILE: include/ws2_32.h
|
||||
* PURPOSE: WinSock 2 DLL header
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
/* DATA **********************************************************************/
|
||||
|
||||
typedef struct _WSH_HELPER_CONTEXT
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
HANDLE ThreadHandle;
|
||||
HANDLE DllHandle;
|
||||
} WSH_HELPER_CONTEXT, *PWAH_HELPER_CONTEXT;
|
||||
|
||||
LPFN_WSASEND pWSASend;
|
||||
LPFN_WSARECV pWSARecv;
|
||||
LPFN_WSASENDTO pWSASendTo;
|
||||
LPFN_WSARECVFROM pWSARecvFrom;
|
||||
LPFN_WSAGETLASTERROR pWSAGetLastError;
|
||||
LPFN_WSACANCELBLOCKINGCALL pWSACancelBlockingCall;
|
||||
LPFN_WSASETBLOCKINGHOOK pWSASetBlockingHook;
|
||||
LPFN_SELECT pSelect;
|
||||
LPFN_WSASTARTUP pWSAStartup;
|
||||
LPFN_WSACLEANUP pWSACleanup;
|
||||
LPFN_GETSOCKOPT pGetSockOpt;
|
||||
LPFN_WSAIOCTL pWSAIoctl;
|
||||
|
||||
#define APCH (HANDLE)'SOR '
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
CALLBACK
|
||||
ApcThread(ULONG_PTR Context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
WINAPI
|
||||
DoSocketCancel(PVOID Context1,
|
||||
PVOID Context2,
|
||||
PVOID Context3)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
WINAPI
|
||||
DoSocketRequest(PVOID Context1,
|
||||
PVOID Context2,
|
||||
PVOID Context3)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
CALLBACK
|
||||
ExitThreadApc(ULONG_PTR Context)
|
||||
{
|
||||
PWAH_HELPER_CONTEXT HelperContext = (PWAH_HELPER_CONTEXT)Context;
|
||||
|
||||
/* Close the file handle */
|
||||
CloseHandle(HelperContext->FileHandle);
|
||||
|
||||
/* Free the context */
|
||||
HeapFree(GlobalHeap, 0, HelperContext);
|
||||
|
||||
/* Exit the thread and library */
|
||||
FreeLibraryAndExitThread(HelperContext->DllHandle, ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseHandleHelper(IN HANDLE HelperHandle)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
PWAH_HELPER_CONTEXT Context = HelperHandle;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Validate the handle */
|
||||
if (!Context) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
/* Queue an APC to exit the thread */
|
||||
if (QueueUserAPC(ExitThreadApc, Context->ThreadHandle, (ULONG_PTR)Context))
|
||||
{
|
||||
/* Done */
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We failed somewhere */
|
||||
return ERROR_GEN_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseSocketHandle(IN HANDLE HelperHandle,
|
||||
IN SOCKET Socket)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
PWAH_HELPER_CONTEXT Context = HelperHandle;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Validate the handle */
|
||||
if (!(Context) || (Socket == INVALID_SOCKET) || !(Socket))
|
||||
{
|
||||
/* Invalid handle and/or socket */
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Just close the handle and return */
|
||||
CloseHandle((HANDLE)Socket);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCreateSocketHandle(IN HANDLE HelperHandle,
|
||||
OUT SOCKET *Socket)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
INT OpenType;
|
||||
DWORD Size = sizeof(OpenType);
|
||||
DWORD CreateOptions = 0;
|
||||
UNICODE_STRING Name;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PFILE_FULL_EA_INFORMATION Ea;
|
||||
PWAH_EA_DATA EaData;
|
||||
CHAR EaBuffer[sizeof(*Ea) + sizeof(*EaData)];
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PWAH_HELPER_CONTEXT Context = (PWAH_HELPER_CONTEXT)HelperHandle;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Validate the handle and pointer */
|
||||
if (!(Context) || !(Socket))
|
||||
{
|
||||
/* Invalid handle and/or socket */
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Set pointer to EA */
|
||||
Ea = (PFILE_FULL_EA_INFORMATION)EaBuffer;
|
||||
|
||||
/* Get the open type to determine the create options */
|
||||
if ((pGetSockOpt(INVALID_SOCKET,
|
||||
SOL_SOCKET,
|
||||
SO_OPENTYPE,
|
||||
(PCHAR)&OpenType,
|
||||
(INT FAR*)&Size) == ERROR_SUCCESS) && (OpenType))
|
||||
{
|
||||
/* This is a sync open */
|
||||
CreateOptions = FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
}
|
||||
|
||||
/* Initialize the attributes for the driver */
|
||||
RtlInitUnicodeString(&Name, L"\\Device\\WS2IFSL\\NifsSct");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&Name,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Set up the EA */
|
||||
Ea->NextEntryOffset = 0;
|
||||
Ea->Flags = 0;
|
||||
Ea->EaNameLength = sizeof("NifsSct");
|
||||
Ea->EaValueLength = sizeof(*EaData);
|
||||
RtlCopyMemory(Ea->EaName, "NifsSct", Ea->EaNameLength);
|
||||
|
||||
/* Get our EA data */
|
||||
EaData = (PWAH_EA_DATA)(Ea + 1);
|
||||
|
||||
/* Write the EA Data */
|
||||
EaData->FileHandle = Context->FileHandle;
|
||||
EaData->Context = NULL;
|
||||
|
||||
/* Call the driver */
|
||||
Status = NtCreateFile((PHANDLE)Socket,
|
||||
FILE_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0,
|
||||
FILE_OPEN_IF,
|
||||
CreateOptions,
|
||||
Ea,
|
||||
sizeof(*Ea) + sizeof(*EaData));
|
||||
|
||||
/* Check for success */
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Write the socket handle */
|
||||
EaData->Context =(HANDLE)*Socket;
|
||||
|
||||
/* Tell the driver about it */
|
||||
if (DeviceIoControl((HANDLE)*Socket,
|
||||
IOCTL_WS2IFSL_SET_HANDLE,
|
||||
&EaData,
|
||||
sizeof(WSH_EA_DATA),
|
||||
NULL,
|
||||
0,
|
||||
&Size,
|
||||
NULL))
|
||||
{
|
||||
/* Set success */
|
||||
ErrorCode = NO_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We failed. Get the error and close the socket */
|
||||
ErrorCode = GetLastError();
|
||||
CloseHandle((HANDLE)*Socket);
|
||||
*Socket = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create file failed, conver error code */
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
/* Return to caller */
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
WahDisableNonIFSHandleSupport(VOID)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
SC_HANDLE ServiceMgrHandle, Ws2IfsHandle;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Open the service DB */
|
||||
ServiceMgrHandle = OpenSCManager(NULL,
|
||||
SERVICES_ACTIVE_DATABASE,
|
||||
SC_MANAGER_CREATE_SERVICE);
|
||||
if (!ServiceMgrHandle) return GetLastError();
|
||||
|
||||
/* Open the service */
|
||||
Ws2IfsHandle = OpenService(ServiceMgrHandle, "WS2IFSL", SERVICE_ALL_ACCESS);
|
||||
|
||||
/* Disable the servce */
|
||||
ChangeServiceConfig(Ws2IfsHandle,
|
||||
SERVICE_NO_CHANGE,
|
||||
SERVICE_DISABLED,
|
||||
SERVICE_NO_CHANGE,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Close the handles and return */
|
||||
CloseServiceHandle(ServiceMgrHandle);
|
||||
CloseServiceHandle(Ws2IfsHandle);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
WahEnableNonIFSHandleSupport(VOID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahOpenHandleHelper(OUT PHANDLE HelperHandle)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
HINSTANCE hWs2_32;
|
||||
UNICODE_STRING Name;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PFILE_FULL_EA_INFORMATION Ea;
|
||||
PWAH_EA_DATA2 EaData;
|
||||
CHAR EaBuffer[sizeof(*Ea) + sizeof(*EaData)];
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
DWORD Tid;
|
||||
PWAH_HELPER_CONTEXT Context;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Validate the pointer */
|
||||
if (!HelperHandle)
|
||||
{
|
||||
/* Invalid handle and/or socket */
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Get ws2_32.dll's handle. We don't load it: it MUST be here */
|
||||
hWs2_32 = GetModuleHandle ("WS2_32.DLL");
|
||||
if (!hWs2_32) return WSASYSCALLFAILURE;
|
||||
|
||||
/* Dynamically load all its APIs */
|
||||
if (!((pGetSockOpt = (LPFN_GETSOCKOPT)GetProcAddress(hWs2_32, "getsockopt"))) ||
|
||||
!((pSelect = (LPFN_SELECT)GetProcAddress(hWs2_32, "select"))) ||
|
||||
!((pWSACancelBlockingCall = (LPFN_WSACANCELBLOCKINGCALL)GetProcAddress(hWs2_32, "WSACancelBlockingCall"))) ||
|
||||
!((pWSACleanup = (LPFN_WSACLEANUP)GetProcAddress(hWs2_32, "WSACleanup"))) ||
|
||||
!((pWSAGetLastError = (LPFN_WSAGETLASTERROR)GetProcAddress(hWs2_32, "WSAGetLastError"))) ||
|
||||
!((pWSASetBlockingHook = (LPFN_WSASETBLOCKINGHOOK)GetProcAddress(hWs2_32, "WSASetBlockingHook"))) ||
|
||||
!((pWSARecv = (LPFN_WSARECV)GetProcAddress(hWs2_32, "WSARecv"))) ||
|
||||
!((pWSASend = (LPFN_WSASEND)GetProcAddress(hWs2_32, "WSASend"))) ||
|
||||
!((pWSASendTo = (LPFN_WSASENDTO)GetProcAddress(hWs2_32, "WSASendTo"))) ||
|
||||
!((pWSAStartup = (LPFN_WSASTARTUP)GetProcAddress(hWs2_32, "WSAStartup"))) ||
|
||||
!((pWSARecvFrom = (LPFN_WSARECVFROM)GetProcAddress(hWs2_32, "WSARecvFrom"))) ||
|
||||
!((pWSAIoctl = (LPFN_WSAIOCTL)GetProcAddress(hWs2_32, "WSAIoctl"))))
|
||||
{
|
||||
/* Uh, guess we failed somewhere */
|
||||
return WSASYSCALLFAILURE;
|
||||
}
|
||||
|
||||
/* Set pointer EA structure */
|
||||
Ea = (PFILE_FULL_EA_INFORMATION)EaBuffer;
|
||||
|
||||
/* Create the helper context */
|
||||
Context = HeapAlloc(GlobalHeap, 0, sizeof(WSH_HELPER_CONTEXT));
|
||||
if (Context)
|
||||
{
|
||||
/* Create the special request thread */
|
||||
Context->ThreadHandle = CreateThread(NULL,
|
||||
0,
|
||||
(PVOID)ApcThread,
|
||||
Context,
|
||||
CREATE_SUSPENDED,
|
||||
&Tid);
|
||||
if (Context->ThreadHandle)
|
||||
{
|
||||
/* Create the attributes for the driver open */
|
||||
RtlInitUnicodeString(&Name, L"\\Device\\WS2IFSL\\NifsPvd");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&Name,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Setup the EA */
|
||||
Ea->NextEntryOffset = 0;
|
||||
Ea->Flags = 0;
|
||||
Ea->EaNameLength = sizeof("NifsPvd");
|
||||
Ea->EaValueLength = sizeof(*EaData);
|
||||
RtlCopyMemory(Ea->EaName, "NifsPvd", Ea->EaNameLength);
|
||||
|
||||
/* Get our EA data */
|
||||
EaData = (PWAH_EA_DATA2)(Ea + 1);
|
||||
|
||||
/* Fill out the EA Data */
|
||||
EaData->ThreadHandle = Context->ThreadHandle;
|
||||
EaData->RequestRoutine = DoSocketRequest;
|
||||
EaData->CancelRoutine = DoSocketCancel;
|
||||
EaData->ApcContext = Context;
|
||||
EaData->Reserved = 0;
|
||||
|
||||
/* Call the driver */
|
||||
Status = NtCreateFile(&Context->FileHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0,
|
||||
FILE_OPEN_IF,
|
||||
0,
|
||||
Ea,
|
||||
sizeof(*Ea) + sizeof(*EaData));
|
||||
|
||||
/* Check for success */
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Resume the thread and return a handle to the context */
|
||||
ResumeThread(Context->ThreadHandle);
|
||||
*HelperHandle = (HANDLE)Context;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the error code */
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
/* We failed, mark us as such */
|
||||
Context->FileHandle = NULL;
|
||||
ResumeThread(Context->ThreadHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the error code */
|
||||
ErrorCode = GetLastError();
|
||||
}
|
||||
|
||||
/* If we got here, we failed, so free the context */
|
||||
HeapFree(GlobalHeap, 0, Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the errror code */
|
||||
ErrorCode = GetLastError();
|
||||
}
|
||||
|
||||
/* Return to caller */
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCompleteRequest(IN HANDLE HelperHandle,
|
||||
IN SOCKET Socket,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN DWORD ErrorCode,
|
||||
IN DWORD BytesTransferred)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(HelperHandle);
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
UNREFERENCED_PARAMETER(lpOverlapped);
|
||||
UNREFERENCED_PARAMETER(ErrorCode);
|
||||
UNREFERENCED_PARAMETER(BytesTransferred);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
87
reactos/dll/win32/ws2help_new/notify.c
Normal file
87
reactos/dll/win32/ws2help_new/notify.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 DLL
|
||||
* FILE: include/ws2_32.h
|
||||
* PURPOSE: WinSock 2 DLL header
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
/* DATA **********************************************************************/
|
||||
|
||||
#define HANH (HANDLE)'2SOR'
|
||||
|
||||
PSECURITY_DESCRIPTOR pSDPipe = NULL;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseNotificationHandleHelper(IN HANDLE HelperHandle)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Validate handle */
|
||||
if (HelperHandle != HANH) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
/* return */
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCreateNotificationHandle(IN HANDLE HelperHandle,
|
||||
OUT PHANDLE NotificationHelperHandle)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(HelperHandle);
|
||||
UNREFERENCED_PARAMETER(NotificationHelperHandle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahOpenNotificationHandleHelper(OUT PHANDLE HelperHandle)
|
||||
{
|
||||
DWORD ErrorCode;
|
||||
|
||||
/* Enter the prolog, make sure we're initialized */
|
||||
ErrorCode = WS2HELP_PROLOG();
|
||||
if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
|
||||
|
||||
/* Validate handle */
|
||||
if (!HelperHandle) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
/* Return a bogus handle ("ROS2") */
|
||||
*HelperHandle = HANH;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
WahNotifyAllProcesses(IN HANDLE NotificationHelperHandle)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(NotificationHelperHandle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
WahWaitForNotification(IN HANDLE NotificationHelperHandle,
|
||||
IN HANDLE lpNotificationHandle,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(NotificationHelperHandle);
|
||||
UNREFERENCED_PARAMETER(lpNotificationHandle);
|
||||
UNREFERENCED_PARAMETER(lpOverlapped);
|
||||
UNREFERENCED_PARAMETER(lpCompletionRoutine);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
47
reactos/dll/win32/ws2help_new/precomp.h
Normal file
47
reactos/dll/win32/ws2help_new/precomp.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 Helper DLL
|
||||
* FILE: lib/ws2help/precomp.h
|
||||
* PURPOSE: WinSock 2 Helper DLL
|
||||
*/
|
||||
#ifndef __PRECOMP_H
|
||||
#define __PRECOMP_H
|
||||
|
||||
/* Winsock Provider Headers */
|
||||
#define WIN32_NO_STATUS
|
||||
#define _WIN32_WINNT 0x502
|
||||
#define NTOS_MODE_USER
|
||||
#define INCL_WINSOCK_API_TYPEDEFS 1
|
||||
#include <ws2spi.h>
|
||||
|
||||
/* NDK Headers */
|
||||
#include <rtlfuncs.h>
|
||||
#include <iofuncs.h>
|
||||
|
||||
/* Shared Winsock Helper headers */
|
||||
#include <ws2help.h>
|
||||
#include <wshdrv.h>
|
||||
|
||||
/* Missing definition */
|
||||
#define SO_OPENTYPE 0x20
|
||||
|
||||
/* Global data */
|
||||
extern HANDLE GlobalHeap;
|
||||
extern PSECURITY_DESCRIPTOR pSDPipe;
|
||||
extern HANDLE ghWriterEvent;
|
||||
extern BOOL Ws2helpInitialized;
|
||||
extern DWORD gdwSpinCount;
|
||||
extern DWORD gHandleToIndexMask;
|
||||
|
||||
/* Functions */
|
||||
DWORD
|
||||
WINAPI
|
||||
Ws2helpInitialize(VOID);
|
||||
|
||||
/* Initialization macro */
|
||||
#define WS2HELP_PROLOG() \
|
||||
(Ws2helpInitialized? ERROR_SUCCESS : Ws2helpInitialize())
|
||||
|
||||
#endif /* __WS2HELP_H */
|
||||
|
||||
/* EOF */
|
163
reactos/dll/win32/ws2help_new/ws2help.h
Normal file
163
reactos/dll/win32/ws2help_new/ws2help.h
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 Helper DLL
|
||||
* FILE: include/libs/winsock/ws2help.h
|
||||
* PURPOSE: WinSock 2 Helper DLL header
|
||||
*/
|
||||
|
||||
#ifndef __WS2HELP_H
|
||||
#define __WS2HELP_H
|
||||
|
||||
/* Types */
|
||||
typedef struct _WSH_HANDLE
|
||||
{
|
||||
LONG RefCount;
|
||||
HANDLE Handle;
|
||||
} WSH_HANDLE, *PWAH_HANDLE;
|
||||
|
||||
typedef struct _WSH_HASH_TABLE
|
||||
{
|
||||
DWORD Size;
|
||||
PWAH_HANDLE Handles[1];
|
||||
} WSH_HASH_TABLE, *PWAH_HASH_TABLE;
|
||||
|
||||
typedef struct _WSH_SEARCH_TABLE
|
||||
{
|
||||
volatile PWAH_HASH_TABLE HashTable;
|
||||
volatile PLONG CurrentCount;
|
||||
LONG Count1;
|
||||
LONG Count2;
|
||||
LONG SpinCount;
|
||||
BOOL Expanding;
|
||||
CRITICAL_SECTION Lock;
|
||||
} WSH_SEARCH_TABLE, *PWAH_SEARCH_TABLE;
|
||||
|
||||
typedef struct _WSH_HANDLE_TABLE
|
||||
{
|
||||
DWORD Mask;
|
||||
WSH_SEARCH_TABLE SearchTables[1];
|
||||
} WSH_HANDLE_TABLE, *PWAH_HANDLE_TABLE;
|
||||
|
||||
//typedef struct _WSH_HANDLE_TABLE *PWAH_HANDLE_TABLE;
|
||||
|
||||
typedef BOOL
|
||||
(WINAPI *PWAH_HANDLE_ENUMERATE_PROC)(
|
||||
IN PVOID Context,
|
||||
IN PWAH_HANDLE Handle
|
||||
);
|
||||
|
||||
PWAH_HANDLE
|
||||
WINAPI
|
||||
WahReferenceContextByHandle(
|
||||
IN PWAH_HANDLE_TABLE Table,
|
||||
IN HANDLE Handle
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahRemoveHandleContext(
|
||||
IN PWAH_HANDLE_TABLE Table,
|
||||
IN PWAH_HANDLE Handle
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseSocketHandle(
|
||||
IN HANDLE HelperHandle,
|
||||
IN SOCKET Socket
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahOpenCurrentThread(
|
||||
IN HANDLE HelperHandle,
|
||||
OUT LPWSATHREADID ThreadId
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseApcHelper(
|
||||
IN HANDLE HelperHandle
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseThread(
|
||||
IN HANDLE HelperHandle,
|
||||
IN LPWSATHREADID ThreadId
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseHandleHelper(
|
||||
IN HANDLE HelperHandle
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCloseNotificationHandleHelper(
|
||||
IN HANDLE HelperHandle
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahOpenNotificationHandleHelper(
|
||||
OUT PHANDLE HelperHandle
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCreateNotificationHandle(
|
||||
IN HANDLE HelperHandle,
|
||||
OUT PHANDLE NotificationHelperHandle
|
||||
);
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
WahWaitForNotification(
|
||||
IN HANDLE NotificationHelperHandle,
|
||||
IN HANDLE lpNotificationHandle,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
|
||||
);
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
WahNotifyAllProcesses(
|
||||
IN HANDLE NotificationHelperHandle
|
||||
);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
WahEnumerateHandleContexts(
|
||||
IN PWAH_HANDLE_TABLE Table,
|
||||
IN PWAH_HANDLE_ENUMERATE_PROC Callback,
|
||||
IN PVOID Context
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahCreateHandleContextTable(
|
||||
OUT PWAH_HANDLE_TABLE *Table
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahDestroyHandleContextTable(
|
||||
IN PWAH_HANDLE_TABLE Table
|
||||
);
|
||||
|
||||
PWAH_HANDLE
|
||||
WINAPI
|
||||
WahInsertHandleContext(
|
||||
IN PWAH_HANDLE_TABLE Table,
|
||||
IN PWAH_HANDLE Handle
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
WahOpenApcHelper(
|
||||
OUT PHANDLE ApcHelperHandle
|
||||
);
|
||||
|
||||
#endif
|
14
reactos/dll/win32/ws2help_new/ws2help.rbuild
Normal file
14
reactos/dll/win32/ws2help_new/ws2help.rbuild
Normal file
|
@ -0,0 +1,14 @@
|
|||
<module name="ws2help" type="win32dll" baseaddress="${BASEADDRESS_WS2HELP}" installbase="system32" installname="ws2help.dll">
|
||||
<importlibrary definition="ws2help.spec" />
|
||||
<include base="ws2help">.</include>
|
||||
<library>advapi32</library>
|
||||
<library>ntdll</library>
|
||||
<library>kernel32</library>
|
||||
<library>ws2_32</library>
|
||||
<file>apc.c</file>
|
||||
<file>context.c</file>
|
||||
<file>dllmain.c</file>
|
||||
<file>handle.c</file>
|
||||
<file>notify.c</file>
|
||||
<file>ws2help.rc</file>
|
||||
</module>
|
7
reactos/dll/win32/ws2help_new/ws2help.rc
Normal file
7
reactos/dll/win32/ws2help_new/ws2help.rc
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* $Id: ws2help.rc 12852 2005-01-06 13:58:04Z mf $ */
|
||||
|
||||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "Windows Sockets 2 Helper API\0"
|
||||
#define REACTOS_STR_INTERNAL_NAME "ws2help\0"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "ws2help.dll\0"
|
||||
#include <reactos/version.rc>
|
23
reactos/dll/win32/ws2help_new/ws2help.spec
Normal file
23
reactos/dll/win32/ws2help_new/ws2help.spec
Normal file
|
@ -0,0 +1,23 @@
|
|||
@ stdcall WahCloseApcHelper(long)
|
||||
@ stdcall WahCloseHandleHelper(long)
|
||||
@ stdcall WahCloseNotificationHandleHelper(long)
|
||||
@ stdcall WahCloseSocketHandle(long ptr)
|
||||
@ stdcall WahCloseThread(long ptr)
|
||||
@ stdcall WahCompleteRequest(long ptr ptr long long)
|
||||
@ stdcall WahCreateHandleContextTable(ptr)
|
||||
@ stdcall WahCreateNotificationHandle(long ptr)
|
||||
@ stdcall WahCreateSocketHandle(long ptr)
|
||||
@ stdcall WahDestroyHandleContextTable(ptr)
|
||||
@ stdcall WahDisableNonIFSHandleSupport()
|
||||
@ stdcall WahEnableNonIFSHandleSupport()
|
||||
@ stdcall WahEnumerateHandleContexts(ptr ptr ptr)
|
||||
@ stdcall WahInsertHandleContext(ptr ptr)
|
||||
@ stdcall WahNotifyAllProcesses(long)
|
||||
@ stdcall WahOpenApcHelper(ptr)
|
||||
@ stdcall WahOpenCurrentThread(long ptr)
|
||||
@ stdcall WahOpenHandleHelper(ptr)
|
||||
@ stdcall WahOpenNotificationHandleHelper(ptr)
|
||||
@ stdcall WahQueueUserApc(long ptr ptr ptr)
|
||||
@ stdcall WahReferenceContextByHandle(ptr long)
|
||||
@ stdcall WahRemoveHandleContext(ptr ptr)
|
||||
@ stdcall WahWaitForNotification(long long ptr ptr)
|
28
reactos/dll/win32/ws2help_new/wshdrv.h
Normal file
28
reactos/dll/win32/ws2help_new/wshdrv.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 DLL
|
||||
* FILE: include/drivers/ws2ifsl/wshdrv.h
|
||||
* PURPOSE: WinSock 2 Helper Driver header
|
||||
*/
|
||||
|
||||
#ifndef __WSHDRV_H
|
||||
#define __WSHDRV_H
|
||||
|
||||
typedef struct _WSH_EA_DATA
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
PVOID Context;
|
||||
} WSH_EA_DATA, *PWAH_EA_DATA;
|
||||
|
||||
typedef struct _WAH_EA_DATA2
|
||||
{
|
||||
HANDLE ThreadHandle;
|
||||
PVOID RequestRoutine;
|
||||
PVOID CancelRoutine;
|
||||
PVOID ApcContext;
|
||||
ULONG Reserved;
|
||||
} WAH_EA_DATA2, *PWAH_EA_DATA2;
|
||||
|
||||
#define IOCTL_WS2IFSL_SET_HANDLE 0x12B00
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue