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