src/os/win32/ngx_win32_init.c - nginx source code

Global variables defined

Data types defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <nginx.h>


  8. ngx_uint_t  ngx_win32_version;
  9. ngx_uint_t  ngx_ncpu;
  10. ngx_uint_t  ngx_max_wsabufs;
  11. ngx_int_t   ngx_max_sockets;
  12. ngx_uint_t  ngx_inherited_nonblocking = 1;
  13. ngx_uint_t  ngx_tcp_nodelay_and_tcp_nopush;

  14. char        ngx_unique[NGX_INT32_LEN + 1];


  15. ngx_os_io_t ngx_os_io = {
  16.     ngx_wsarecv,
  17.     ngx_wsarecv_chain,
  18.     ngx_udp_wsarecv,
  19.     ngx_wsasend,
  20.     NULL,
  21.     NULL,
  22.     ngx_wsasend_chain,
  23.     0
  24. };


  25. typedef struct {
  26.     WORD  wServicePackMinor;
  27.     WORD  wSuiteMask;
  28.     BYTE  wProductType;
  29. } ngx_osviex_stub_t;


  30. static u_int               osviex;
  31. static OSVERSIONINFOEX     osvi;

  32. /* Should these pointers be per protocol ? */
  33. LPFN_ACCEPTEX              ngx_acceptex;
  34. LPFN_GETACCEPTEXSOCKADDRS  ngx_getacceptexsockaddrs;
  35. LPFN_TRANSMITFILE          ngx_transmitfile;
  36. LPFN_TRANSMITPACKETS       ngx_transmitpackets;
  37. LPFN_CONNECTEX             ngx_connectex;
  38. LPFN_DISCONNECTEX          ngx_disconnectex;

  39. static GUID ax_guid = WSAID_ACCEPTEX;
  40. static GUID as_guid = WSAID_GETACCEPTEXSOCKADDRS;
  41. static GUID tf_guid = WSAID_TRANSMITFILE;
  42. static GUID tp_guid = WSAID_TRANSMITPACKETS;
  43. static GUID cx_guid = WSAID_CONNECTEX;
  44. static GUID dx_guid = WSAID_DISCONNECTEX;


  45. #if (NGX_LOAD_WSAPOLL)
  46. ngx_wsapoll_pt             WSAPoll;
  47. ngx_uint_t                 ngx_have_wsapoll;
  48. #endif


  49. ngx_int_t
  50. ngx_os_init(ngx_log_t *log)
  51. {
  52.     DWORD         bytes;
  53.     SOCKET        s;
  54.     WSADATA       wsd;
  55.     ngx_err_t     err;
  56.     ngx_time_t   *tp;
  57.     ngx_uint_t    n;
  58.     SYSTEM_INFO   si;

  59.     /* get Windows version */

  60.     ngx_memzero(&osvi, sizeof(OSVERSIONINFOEX));
  61.     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

  62. #ifdef _MSC_VER
  63. #pragma warning(disable:4996)
  64. #endif

  65.     osviex = GetVersionEx((OSVERSIONINFO *) &osvi);

  66.     if (osviex == 0) {
  67.         osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  68.         if (GetVersionEx((OSVERSIONINFO *) &osvi) == 0) {
  69.             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  70.                           "GetVersionEx() failed");
  71.             return NGX_ERROR;
  72.         }
  73.     }

  74. #ifdef _MSC_VER
  75. #pragma warning(default:4996)
  76. #endif

  77.     /*
  78.      *  Windows 3.1 Win32s   0xxxxx
  79.      *
  80.      *  Windows 95           140000
  81.      *  Windows 98           141000
  82.      *  Windows ME           149000
  83.      *  Windows NT 3.51      235100
  84.      *  Windows NT 4.0       240000
  85.      *  Windows NT 4.0 SP5   240050
  86.      *  Windows 2000         250000
  87.      *  Windows XP           250100
  88.      *  Windows 2003         250200
  89.      *  Windows Vista/2008   260000
  90.      *
  91.      *  Windows CE x.x       3xxxxx
  92.      */

  93.     ngx_win32_version = osvi.dwPlatformId * 100000
  94.                         + osvi.dwMajorVersion * 10000
  95.                         + osvi.dwMinorVersion * 100;

  96.     if (osviex) {
  97.         ngx_win32_version += osvi.wServicePackMajor * 10
  98.                              + osvi.wServicePackMinor;
  99.     }

  100.     GetSystemInfo(&si);
  101.     ngx_pagesize = si.dwPageSize;
  102.     ngx_allocation_granularity = si.dwAllocationGranularity;
  103.     ngx_ncpu = si.dwNumberOfProcessors;
  104.     ngx_cacheline_size = NGX_CPU_CACHE_LINE;

  105.     for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }

  106.     /* delete default "C" locale for _wcsicmp() */
  107.     setlocale(LC_ALL, "");


  108.     /* init Winsock */

  109.     if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
  110.         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  111.                       "WSAStartup() failed");
  112.         return NGX_ERROR;
  113.     }

  114.     if (ngx_win32_version < NGX_WIN_NT) {
  115.         ngx_max_wsabufs = 16;
  116.         return NGX_OK;
  117.     }

  118.     /* STUB: ngx_uint_t max */
  119.     ngx_max_wsabufs = 1024 * 1024;

  120.     /*
  121.      * get AcceptEx(), GetAcceptExSockAddrs(), TransmitFile(),
  122.      * TransmitPackets(), ConnectEx(), and DisconnectEx() addresses
  123.      */

  124.     s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  125.     if (s == (ngx_socket_t) -1) {
  126.         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  127.                       ngx_socket_n " failed");
  128.         return NGX_ERROR;
  129.     }

  130.     if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ax_guid, sizeof(GUID),
  131.                  &ngx_acceptex, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL)
  132.         == -1)
  133.     {
  134.         ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
  135.                       "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
  136.                                "WSAID_ACCEPTEX) failed");
  137.     }

  138.     if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &as_guid, sizeof(GUID),
  139.                  &ngx_getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
  140.                  &bytes, NULL, NULL)
  141.         == -1)
  142.     {
  143.         ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
  144.                       "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
  145.                                "WSAID_GETACCEPTEXSOCKADDRS) failed");
  146.     }

  147.     if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tf_guid, sizeof(GUID),
  148.                  &ngx_transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes,
  149.                  NULL, NULL)
  150.         == -1)
  151.     {
  152.         ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
  153.                       "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
  154.                                "WSAID_TRANSMITFILE) failed");
  155.     }

  156.     if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tp_guid, sizeof(GUID),
  157.                  &ngx_transmitpackets, sizeof(LPFN_TRANSMITPACKETS), &bytes,
  158.                  NULL, NULL)
  159.         == -1)
  160.     {
  161.         ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
  162.                       "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
  163.                                "WSAID_TRANSMITPACKETS) failed");
  164.     }

  165.     if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &cx_guid, sizeof(GUID),
  166.                  &ngx_connectex, sizeof(LPFN_CONNECTEX), &bytes,
  167.                  NULL, NULL)
  168.         == -1)
  169.     {
  170.         ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
  171.                       "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
  172.                                "WSAID_CONNECTEX) failed");
  173.     }

  174.     if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &dx_guid, sizeof(GUID),
  175.                  &ngx_disconnectex, sizeof(LPFN_DISCONNECTEX), &bytes,
  176.                  NULL, NULL)
  177.         == -1)
  178.     {
  179.         ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
  180.                       "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
  181.                                "WSAID_DISCONNECTEX) failed");
  182.     }

  183.     if (ngx_close_socket(s) == -1) {
  184.         ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
  185.                       ngx_close_socket_n " failed");
  186.     }

  187. #if (NGX_LOAD_WSAPOLL)
  188.     {
  189.     HMODULE  hmod;

  190.     hmod = GetModuleHandle("ws2_32.dll");
  191.     if (hmod == NULL) {
  192.         ngx_log_error(NGX_LOG_NOTICE, log, ngx_errno,
  193.                       "GetModuleHandle(\"ws2_32.dll\") failed");
  194.         goto nopoll;
  195.     }

  196.     WSAPoll = (ngx_wsapoll_pt) (void *) GetProcAddress(hmod, "WSAPoll");
  197.     if (WSAPoll == NULL) {
  198.         ngx_log_error(NGX_LOG_NOTICE, log, ngx_errno,
  199.                       "GetProcAddress(\"WSAPoll\") failed");
  200.         goto nopoll;
  201.     }

  202.     ngx_have_wsapoll = 1;

  203.     }

  204. nopoll:

  205. #endif

  206.     if (GetEnvironmentVariable("ngx_unique", ngx_unique, NGX_INT32_LEN + 1)
  207.         != 0)
  208.     {
  209.         ngx_process = NGX_PROCESS_WORKER;

  210.     } else {
  211.         err = ngx_errno;

  212.         if (err != ERROR_ENVVAR_NOT_FOUND) {
  213.             ngx_log_error(NGX_LOG_EMERG, log, err,
  214.                           "GetEnvironmentVariable(\"ngx_unique\") failed");
  215.             return NGX_ERROR;
  216.         }

  217.         ngx_sprintf((u_char *) ngx_unique, "%P%Z", ngx_pid);
  218.     }

  219.     tp = ngx_timeofday();
  220.     srand((ngx_pid << 16) ^ (unsigned) tp->sec ^ tp->msec);

  221.     return NGX_OK;
  222. }


  223. void
  224. ngx_os_status(ngx_log_t *log)
  225. {
  226.     ngx_osviex_stub_t  *osviex_stub;

  227.     ngx_log_error(NGX_LOG_NOTICE, log, 0, NGINX_VER_BUILD);

  228.     if (osviex) {

  229.         /*
  230.          * the MSVC 6.0 SP2 defines wSuiteMask and wProductType
  231.          * as WORD wReserved[2]
  232.          */
  233.         osviex_stub = (ngx_osviex_stub_t *) &osvi.wServicePackMinor;

  234.         ngx_log_error(NGX_LOG_INFO, log, 0,
  235.                       "OS: %ui build:%ud, \"%s\", suite:%Xd, type:%ud",
  236.                       ngx_win32_version, osvi.dwBuildNumber, osvi.szCSDVersion,
  237.                       osviex_stub->wSuiteMask, osviex_stub->wProductType);

  238.     } else {
  239.         if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {

  240.             /* Win9x build */

  241.             ngx_log_error(NGX_LOG_INFO, log, 0,
  242.                           "OS: %ui build:%ud.%ud.%ud, \"%s\"",
  243.                           ngx_win32_version,
  244.                           osvi.dwBuildNumber >> 24,
  245.                           (osvi.dwBuildNumber >> 16) & 0xff,
  246.                           osvi.dwBuildNumber & 0xffff,
  247.                           osvi.szCSDVersion);

  248.         } else {

  249.             /*
  250.              * VER_PLATFORM_WIN32_NT
  251.              *
  252.              * we do not currently support VER_PLATFORM_WIN32_CE
  253.              * and we do not support VER_PLATFORM_WIN32s at all
  254.              */

  255.             ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %ui build:%ud, \"%s\"",
  256.                           ngx_win32_version, osvi.dwBuildNumber,
  257.                           osvi.szCSDVersion);
  258.         }
  259.     }
  260. }