dllmain.c

来自「一个类似windows」· C语言 代码 · 共 780 行 · 第 1/2 页

C
780
字号
      Count = Provider->ProcTable.lpWSPSelect(
	  nfds, readfds, writefds, exceptfds, (LPTIMEVAL)timeout, &Errno);
      
      WS_DbgPrint(MAX_TRACE, ("[%x] Select: Count %d Errno %x\n", 
			      Provider, Count, Errno));
      
      DereferenceProviderByPointer(Provider);
      
      if (Errno != NO_ERROR) {
	  WSASetLastError(Errno);
	  return SOCKET_ERROR;
      }
  } else {
      WSASetLastError(WSAEINVAL);
      return SOCKET_ERROR;
  }

  return Count;
}


/*
 * @implemented
 */
INT
EXPORT
bind(
  IN  SOCKET s,
  IN  CONST struct sockaddr *name,
  IN  INT namelen)
{
  PCATALOG_ENTRY Provider;
  INT Status;
  INT Errno;

  if (!WSAINITIALIZED) {
    WSASetLastError(WSANOTINITIALISED);
    return SOCKET_ERROR;
  }

  if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
    WSASetLastError(WSAENOTSOCK);
    return SOCKET_ERROR;
  }

#if (__W32API_MAJOR_VERSION < 2 || __W32API_MINOR_VERSION < 5)
  Status = Provider->ProcTable.lpWSPBind(
    s, (CONST LPSOCKADDR) name, namelen, &Errno);
#else
  Status = Provider->ProcTable.lpWSPBind(
    s, name, namelen, &Errno);
#endif /* __W32API_MAJOR_VERSION < 2 || __W32API_MINOR_VERSION < 5 */

  DereferenceProviderByPointer(Provider);

  if (Status == SOCKET_ERROR) {
    WSASetLastError(Errno);
  }

  return Status;
}


/*
 * @implemented
 */
INT
EXPORT
listen(
    IN  SOCKET s,
    IN  INT backlog)
{
  PCATALOG_ENTRY Provider;
  INT Status;
  INT Errno;

  if (!WSAINITIALIZED) {
    WSASetLastError(WSANOTINITIALISED);
    return SOCKET_ERROR;
  }

  if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
    WSASetLastError(WSAENOTSOCK);
    return SOCKET_ERROR;
  }

  Status = Provider->ProcTable.lpWSPListen(
    s, backlog, &Errno);

  DereferenceProviderByPointer(Provider);

  if (Status == SOCKET_ERROR) {
    WSASetLastError(Errno);
  }

  return Status;
}


/*
 * @implemented
 */
SOCKET
EXPORT
accept(
  IN  SOCKET s,
  OUT LPSOCKADDR addr,
  OUT INT FAR* addrlen)
{
  return WSAAccept(s, addr, addrlen, NULL, 0);
}


/*
 * @implemented
 */
INT
EXPORT
ioctlsocket(
    IN      SOCKET s,
    IN      LONG cmd,
    IN OUT  ULONG FAR* argp)
{
  return WSAIoctl(s, cmd, argp, sizeof(ULONG), argp, sizeof(ULONG), argp, 0, 0);
}


/*
 * @implemented
 */
SOCKET
EXPORT
WSAAccept(
  IN      SOCKET s,
  OUT     LPSOCKADDR addr,
  IN OUT  LPINT addrlen,
  IN      LPCONDITIONPROC lpfnCondition,
  IN      DWORD dwCallbackData)
{
  PCATALOG_ENTRY Provider;
  SOCKET Socket;
  INT Errno;

  if (!WSAINITIALIZED) {
    WSASetLastError(WSANOTINITIALISED);
    return SOCKET_ERROR;
  }

  if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
    WSASetLastError(WSAENOTSOCK);
    return SOCKET_ERROR;
  }

  WS_DbgPrint(MAX_TRACE,("Calling provider accept\n"));

  Socket = Provider->ProcTable.lpWSPAccept(
    s, addr, addrlen, lpfnCondition, dwCallbackData, &Errno);

  WS_DbgPrint(MAX_TRACE,("Calling provider accept -> Socket %x, Errno %x\n",
			 Socket, Errno));

  DereferenceProviderByPointer(Provider);

  if (Socket == INVALID_SOCKET) {
    WSASetLastError(Errno);
  }

  if( addr ) {
#ifdef DBG
      LPSOCKADDR_IN sa = (LPSOCKADDR_IN)addr;
      WS_DbgPrint(MAX_TRACE,("Returned address: %d %s:%d (len %d)\n", 
                             sa->sin_family,
                             inet_ntoa(sa->sin_addr), 
                             ntohs(sa->sin_port),
                             *addrlen));
#endif
  }

  return Socket;
}


/*
 * @implemented
 */
INT
EXPORT
connect(
  IN  SOCKET s,
  IN  CONST struct sockaddr *name,
  IN  INT namelen)
{
  return WSAConnect(s, name, namelen, NULL, NULL, NULL, NULL);
}


/*
 * @implemented
 */
INT
EXPORT
WSAConnect(
  IN  SOCKET s,
  IN  CONST struct sockaddr *name,
  IN  INT namelen,
  IN  LPWSABUF lpCallerData,
  OUT LPWSABUF lpCalleeData,
  IN  LPQOS lpSQOS,
  IN  LPQOS lpGQOS)
{
  PCATALOG_ENTRY Provider;
  INT Status;
  INT Errno;

  if (!WSAINITIALIZED) {
    WSASetLastError(WSANOTINITIALISED);
    return SOCKET_ERROR;
  }

  if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
    WSASetLastError(WSAENOTSOCK);
    return SOCKET_ERROR;
  }

#if (__W32API_MAJOR_VERSION < 2 || __W32API_MINOR_VERSION < 5)
  Status = Provider->ProcTable.lpWSPConnect(
    s, (CONST LPSOCKADDR) name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, &Errno);
#else
  Status = Provider->ProcTable.lpWSPConnect(
    s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, &Errno);
#endif

  DereferenceProviderByPointer(Provider);

  if (Status == SOCKET_ERROR) {
    WSASetLastError(Errno);
  }

  return Status;
}


/*
 * @implemented
 */
INT
EXPORT
WSAIoctl(
    IN  SOCKET s,
    IN  DWORD dwIoControlCode,
    IN  LPVOID lpvInBuffer,
    IN  DWORD cbInBuffer,
    OUT LPVOID lpvOutBuffer,
    IN  DWORD cbOutBuffer,
    OUT LPDWORD lpcbBytesReturned,
    IN  LPWSAOVERLAPPED lpOverlapped,
    IN  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
  PCATALOG_ENTRY Provider;
  INT Status;
  INT Errno;

  if (!WSAINITIALIZED) {
    WSASetLastError(WSANOTINITIALISED);
    return SOCKET_ERROR;
  }

  if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
    WSASetLastError(WSAENOTSOCK);
    return SOCKET_ERROR;
  }

  Status = Provider->ProcTable.lpWSPIoctl(
    s, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer,
    cbOutBuffer, lpcbBytesReturned, lpOverlapped, lpCompletionRoutine,
    NULL /* lpThreadId */, &Errno);

  DereferenceProviderByPointer(Provider);

  if (Status == SOCKET_ERROR) {
    WSASetLastError(Errno);
  }

  return Status;
}

/*
 * @implemented
 */
INT
EXPORT
__WSAFDIsSet(SOCKET s, LPFD_SET set)
{
    unsigned int i;

    for( i = 0; i < set->fd_count; i++ )
	if( set->fd_array[i] == s ) return TRUE;

    return FALSE;
}

void free_winsock_thread_block(PWINSOCK_THREAD_BLOCK p) {
  if(p) {
    if(p->Hostent) { free_hostent(p->Hostent); p->Hostent = 0; }
    if(p->Getservbyname){}
    if(p->Getservbyport) {}


  }
}

BOOL
STDCALL
DllMain(HANDLE hInstDll,
        ULONG dwReason,
        LPVOID lpReserved)
{
  PWINSOCK_THREAD_BLOCK p;

  WS_DbgPrint(MAX_TRACE, ("DllMain of ws2_32.dll.\n"));

  switch (dwReason) {
  case DLL_PROCESS_ATTACH:
    GlobalHeap = GetProcessHeap();

    CreateCatalog();

    InitProviderHandleTable();

    UpcallTable.lpWPUCloseEvent         = WPUCloseEvent;
    UpcallTable.lpWPUCloseSocketHandle  = WPUCloseSocketHandle;
    UpcallTable.lpWPUCreateEvent        = WPUCreateEvent;
    UpcallTable.lpWPUCreateSocketHandle = WPUCreateSocketHandle;
    UpcallTable.lpWPUFDIsSet            = WPUFDIsSet;
    UpcallTable.lpWPUGetProviderPath    = WPUGetProviderPath;
    UpcallTable.lpWPUModifyIFSHandle    = WPUModifyIFSHandle;
    UpcallTable.lpWPUPostMessage        = PostMessageW;
    UpcallTable.lpWPUQueryBlockingCallback    = WPUQueryBlockingCallback;
    UpcallTable.lpWPUQuerySocketHandleContext = WPUQuerySocketHandleContext;
    UpcallTable.lpWPUQueueApc           = WPUQueueApc;
    UpcallTable.lpWPUResetEvent         = WPUResetEvent;
    UpcallTable.lpWPUSetEvent           = WPUSetEvent;
    UpcallTable.lpWPUOpenCurrentThread  = WPUOpenCurrentThread;
    UpcallTable.lpWPUCloseThread        = WPUCloseThread;

    /* Fall through to thread attachment handler */

  case DLL_THREAD_ATTACH:
    p = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_THREAD_BLOCK));

    WS_DbgPrint(MAX_TRACE, ("Thread block at 0x%X.\n", p));
        
    if (!p) {
      return FALSE;
    }

    p->Hostent = NULL;
    p->LastErrorValue = NO_ERROR;
    p->Getservbyname  = NULL;
    p->Getservbyport  = NULL;

    NtCurrentTeb()->WinSockData = p;
    break;

  case DLL_PROCESS_DETACH:
    p = NtCurrentTeb()->WinSockData;

    if (p)
      HeapFree(GlobalHeap, 0, p);

    DestroyCatalog();

    FreeProviderHandleTable();
    break;

  case DLL_THREAD_DETACH:
    p = NtCurrentTeb()->WinSockData;

    if (p)
      HeapFree(GlobalHeap, 0, p);
    break;
  }

  WS_DbgPrint(MAX_TRACE, ("DllMain of ws2_32.dll. Leaving.\n"));

  return TRUE;
}

/* EOF */

⌨️ 快捷键说明

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