/* rndw32.c  -  W32 entropy gatherer
 * Copyright (C) 1999, 2000, 2002, 2003, 2007,
 *               2010 Free Software Foundation, Inc.
 * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-2006
 *
 * This file is part of Libgcrypt.
 *
 *************************************************************************
 * The code here is based on code from Cryptlib 3.0 beta by Peter Gutmann.
 * Source file misc/rndwin32.c "Win32 Randomness-Gathering Code" with this
 * copyright notice:
 *
 * This module is part of the cryptlib continuously seeded pseudorandom
 * number generator.  For usage conditions, see lib_rand.c
 *
 * [Here is the notice from lib_rand.c, which is now called dev_sys.c]
 *
 * This module and the misc/rnd*.c modules represent the cryptlib
 * continuously seeded pseudorandom number generator (CSPRNG) as described in
 * my 1998 Usenix Security Symposium paper "The generation of random numbers
 * for cryptographic purposes".
 *
 * The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
 * 1997, 1998, 1999, all rights reserved.  Redistribution of the CSPRNG
 * modules and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice
 *    and this permission notice in its entirety.
 *
 * 2. Redistributions in binary form must reproduce the copyright notice in
 *    the documentation and/or other materials provided with the distribution.
 *
 * 3. A copy of any bugfixes or enhancements made must be provided to the
 *    author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
 *    baseline version of the code.
 *
 * ALTERNATIVELY, the code may be distributed under the terms of the
 * GNU Lesser General Public License, version 2.1 or any later version
 * published by the Free Software Foundation, in which case the
 * provisions of the GNU LGPL are required INSTEAD OF the above
 * restrictions.
 *
 * Although not required under the terms of the LGPL, it would still
 * be nice if you could make any changes available to the author to
 * allow a consistent code base to be maintained.
 *************************************************************************
 * The above alternative was changed from GPL to LGPL on 2007-08-22 with
 * permission from Peter Gutmann:
 *==========
 From: pgut001 <pgut001@cs.auckland.ac.nz>
 Subject: Re: LGPL for the windows entropy gatherer
 To: wk@gnupg.org
 Date: Wed, 22 Aug 2007 03:05:42 +1200

 Hi,

 >As of now libgcrypt is GPL under Windows due to that module and some people
 >would really like to see it under LGPL too.  Can you do such a license change
 >to LGPL version 2?  Note that LGPL give the user the option to relicense it
 >under GPL, so the change would be pretty easy and backwar compatible.

 Sure.  I assumed that since GPG was GPLd, you'd prefer the GPL for the entropy
 code as well, but Ian asked for LGPL as an option so as of the next release
 I'll have LGPL in there.  You can consider it to be retroactive, so your
 current version will be LGPLd as well.

 Peter.
 *==========
 */

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#ifdef __GNUC__
#include <stdint.h>
#endif

#include <winsock2.h>
#include <windows.h>


#include "types.h"
#include "g10lib.h"
#include "rand-internal.h"


/* Definitions which are missing from the current GNU Windows32Api.  */
#ifndef IOCTL_DISK_PERFORMANCE
#define IOCTL_DISK_PERFORMANCE  0x00070020
#endif

/* This used to be (6*8+5*4+8*2), but Peter Gutmann figured a larger
   value in a newer release. So we use a far larger value. */
#define SIZEOF_DISK_PERFORMANCE_STRUCT 256

/* We don't include wincrypt.h so define it here.  */
#define HCRYPTPROV  HANDLE


/* When we query the performance counters, we allocate an initial buffer and
 * then reallocate it as required until RegQueryValueEx() stops returning
 * ERROR_MORE_DATA.  The following values define the initial buffer size and
 * step size by which the buffer is increased
 */
#define PERFORMANCE_BUFFER_SIZE         65536   /* Start at 64K */
#define PERFORMANCE_BUFFER_STEP         16384   /* Step by 16K */


/* The number of bytes to read from the system RNG on each slow poll.  */
#define SYSTEMRNG_BYTES 64

/* Intel Chipset CSP type and name */
#define PROV_INTEL_SEC  22
#define INTEL_DEF_PROV  "Intel Hardware Cryptographic Service Provider"




/* Type definitions for function pointers to call NetAPI32 functions.  */
typedef DWORD (WINAPI *NETSTATISTICSGET)(LPWSTR szServer, LPWSTR szService,
                                         DWORD dwLevel, DWORD dwOptions,
                                         LPBYTE *lpBuffer);
typedef DWORD (WINAPI *NETAPIBUFFERSIZE)(LPVOID lpBuffer, LPDWORD cbBuffer);
typedef DWORD (WINAPI *NETAPIBUFFERFREE)(LPVOID lpBuffer);

/* Type definitions for function pointers to call native NT functions.  */
typedef DWORD (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD systemInformationClass,
                                                 PVOID systemInformation,
                                                 ULONG systemInformationLength,
                                                 PULONG returnLength);
typedef DWORD (WINAPI *NTQUERYINFORMATIONPROCESS)
     (HANDLE processHandle, DWORD processInformationClass,
      PVOID processInformation, ULONG processInformationLength,
      PULONG returnLength);
typedef DWORD (WINAPI *NTPOWERINFORMATION)
     (DWORD powerInformationClass, PVOID inputBuffer,
      ULONG inputBufferLength, PVOID outputBuffer, ULONG outputBufferLength );

/* Type definitions for function pointers to call CryptoAPI functions. */
typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *phProv,
                                           LPCTSTR pszContainer,
                                           LPCTSTR pszProvider,
                                           DWORD dwProvType,
                                           DWORD dwFlags);
typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,
                                      BYTE *pbBuffer);
typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv, DWORD dwFlags);

/* Somewhat alternative functionality available as a direct call, for
   Windows XP and newer.  This is the CryptoAPI RNG, which isn't anywhere
   near as good as the HW RNG, but we use it if it's present on the basis
   that at least it can't make things any worse.  This direct access version
   is only available under Windows XP, we don't go out of our way to access
   the more general CryptoAPI one since the main purpose of using it is to
   take advantage of any possible future hardware RNGs that may be added,
   for example via TCPA devices.  */
typedef BOOL (WINAPI *RTLGENRANDOM)(PVOID RandomBuffer,
                                    ULONG RandomBufferLength);



/* MBM data structures, originally by Alexander van Kaam, converted to C by
   Anders@Majland.org, finally updated by Chris Zahrt <techn0@iastate.edu> */
#define BusType         char
#define SMBType         char
#define SensorType      char

typedef struct
{
  SensorType iType;               /* Type of sensor.  */
  int Count;                      /* Number of sensor for that type.  */
} SharedIndex;

typedef struct
{
  SensorType ssType;              /* Type of sensor */
  unsigned char ssName[12];       /* Name of sensor */
  char sspadding1[3];             /* Padding of 3 bytes */
  double ssCurrent;               /* Current value */
  double ssLow;                   /* Lowest readout */
  double ssHigh;                  /* Highest readout */
  long ssCount;                   /* Total number of readout */
  char sspadding2[4];             /* Padding of 4 bytes */
  long double ssTotal;            /* Total amout of all readouts */
  char sspadding3[6];             /* Padding of 6 bytes */
  double ssAlarm1;                /* Temp & fan: high alarm; voltage: % off */
  double ssAlarm2;                /* Temp: low alarm */
} SharedSensor;

typedef struct
{
  short siSMB_Base;               /* SMBus base address */
  BusType siSMB_Type;             /* SMBus/Isa bus used to access chip */
  SMBType siSMB_Code;             /* SMBus sub type, Intel, AMD or ALi */
  char siSMB_Addr;                /* Address of sensor chip on SMBus */
  unsigned char siSMB_Name[41];   /* Nice name for SMBus */
  short siISA_Base;               /* ISA base address of sensor chip on ISA */
  int siChipType;                 /* Chip nr, connects with Chipinfo.ini */
  char siVoltageSubType;          /* Subvoltage option selected */
} SharedInfo;

typedef struct
{
  double sdVersion;               /* Version number (example: 51090) */
  SharedIndex sdIndex[10];        /* Sensor index */
  SharedSensor sdSensor[100];     /* Sensor info */
  SharedInfo sdInfo;              /* Misc.info */
  unsigned char sdStart[41];      /* Start time */

  /* We don't use the next two fields both because they're not random
     and because it provides a nice safety margin in case of data size
     mis- estimates (we always under-estimate the buffer size).  */
#if 0
  unsigned char sdCurrent[41];    /* Current time */
  unsigned char sdPath[256];      /* MBM path */
#endif /*0*/
} SharedData;



/* One time intialized handles and function pointers.  We use dynamic
   loading of the DLLs to do without them in case libgcrypt does not
   need any random.  */
static HANDLE hNetAPI32;
static NETSTATISTICSGET pNetStatisticsGet;
static NETAPIBUFFERSIZE pNetApiBufferSize;
static NETAPIBUFFERFREE pNetApiBufferFree;

static HANDLE hNTAPI;
static NTQUERYSYSTEMINFORMATION  pNtQuerySystemInformation;
static NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess;
static NTPOWERINFORMATION        pNtPowerInformation;

static HANDLE hAdvAPI32;
static CRYPTACQUIRECONTEXT pCryptAcquireContext;
static CRYPTGENRANDOM      pCryptGenRandom;
static CRYPTRELEASECONTEXT pCryptReleaseContext;
static RTLGENRANDOM        pRtlGenRandom;


/* Other module global variables.  */
static int system_rng_available; /* Whether a system RNG is available.  */
static HCRYPTPROV hRNGProv;      /* Handle to Intel RNG CSP. */

static int debug_me;  /* Debug flag.  */

static int system_is_w2000;     /* True if running on W2000.  */




/* Try and connect to the system RNG if there's one present. */
static void
init_system_rng (void)
{
  system_rng_available = 0;
  hRNGProv = NULL;

  hAdvAPI32 = GetModuleHandle ("AdvAPI32.dll");
  if (!hAdvAPI32)
    return;

  pCryptAcquireContext = (CRYPTACQUIRECONTEXT)
    GetProcAddress (hAdvAPI32, "CryptAcquireContextA");
  pCryptGenRandom = (CRYPTGENRANDOM)
    GetProcAddress (hAdvAPI32, "CryptGenRandom");
  pCryptReleaseContext = (CRYPTRELEASECONTEXT)
    GetProcAddress (hAdvAPI32, "CryptReleaseContext");

  /* Get a pointer to the native randomness function if it's available.
     This isn't exported by name, so we have to get it by ordinal.  */
  pRtlGenRandom = (RTLGENRANDOM)
    GetProcAddress (hAdvAPI32, "SystemFunction036");

  /* Try and connect to the PIII RNG CSP.  The AMD 768 southbridge (from
     the 760 MP chipset) also has a hardware RNG, but there doesn't appear
     to be any driver support for this as there is for the Intel RNG so we
     can't do much with it.  OTOH the Intel RNG is also effectively dead
     as well, mostly due to virtually nonexistent support/marketing by
     Intel, it's included here mostly for form's sake.  */
  if ( (!pCryptAcquireContext || !pCryptGenRandom || !pCryptReleaseContext
        || !pCryptAcquireContext (&hRNGProv, NULL, INTEL_DEF_PROV,
                                  PROV_INTEL_SEC, 0) )
       && !pRtlGenRandom)
    {
      hAdvAPI32 = NULL;
    }
  else
    system_rng_available = 1;
}


/* Read data from the system RNG if availavle.  */
static void
read_system_rng (void (*add)(const void*, size_t, enum random_origins),
                 enum random_origins requester)
{
  BYTE buffer[ SYSTEMRNG_BYTES + 8 ];
  int quality = 0;

  if (!system_rng_available)
    return;

  /* Read SYSTEMRNG_BYTES bytes from the system RNG.  We don't rely on
     this for all our randomness requirements (particularly the
     software RNG) in case it's broken in some way.  */
  if (hRNGProv)
    {
      if (pCryptGenRandom (hRNGProv, SYSTEMRNG_BYTES, buffer))
        quality = 80;
    }
  else if (pRtlGenRandom)
    {
      if ( pRtlGenRandom (buffer, SYSTEMRNG_BYTES))
        quality = 50;
    }
  if (quality > 0)
    {
      if (debug_me)
        log_debug ("rndw32#read_system_rng: got %d bytes of quality %d\n",
                   SYSTEMRNG_BYTES, quality);
      (*add) (buffer, SYSTEMRNG_BYTES, requester);
      wipememory (buffer, SYSTEMRNG_BYTES);
    }
}


/* Read data from MBM.  This communicates via shared memory, so all we
   need to do is map a file and read the data out.  */
static void
read_mbm_data (void (*add)(const void*, size_t, enum random_origins),
               enum random_origins requester)
{
  HANDLE hMBMData;
  SharedData *mbmDataPtr;

  hMBMData = OpenFileMapping (FILE_MAP_READ, FALSE, "$M$B$M$5$S$D$" );
  if (hMBMData)
    {
      mbmDataPtr = (SharedData*)MapViewOfFile (hMBMData, FILE_MAP_READ,0,0,0);
      if (mbmDataPtr)
        {
          if (debug_me)
            log_debug ("rndw32#read_mbm_data: got %d bytes\n",
                       (int)sizeof (SharedData));
          (*add) (mbmDataPtr, sizeof (SharedData), requester);
          UnmapViewOfFile (mbmDataPtr);
        }
      CloseHandle (hMBMData);
    }
}


/* Fallback method using the registry to poll the statistics.  */
static void
registry_poll (void (*add)(const void*, size_t, enum random_origins),
               enum random_origins requester)
{
  static int cbPerfData = PERFORMANCE_BUFFER_SIZE;
  int iterations;
  DWORD dwSize, status;
  PERF_DATA_BLOCK *pPerfData;

  /* Get information from the system performance counters.  This can take a
     few seconds to do.  In some environments the call to RegQueryValueEx()
     can produce an access violation at some random time in the future, in
     some cases adding a short delay after the following code block makes
     the problem go away.  This problem is extremely difficult to
     reproduce, I haven't been able to get it to occur despite running it
     on a number of machines.  MS knowledge base article Q178887 covers
     this type of problem, it's typically caused by an external driver or
     other program that adds its own values under the
     HKEY_PERFORMANCE_DATA key.  The NT kernel, via Advapi32.dll, calls the
     required external module to map in the data inside an SEH try/except
     block, so problems in the module's collect function don't pop up until
     after it has finished, so the fault appears to occur in Advapi32.dll.
     There may be problems in the NT kernel as well though, a low-level
     memory checker indicated that ExpandEnvironmentStrings() in
     Kernel32.dll, called an interminable number of calls down inside
     RegQueryValueEx(), was overwriting memory (it wrote twice the
     allocated size of a buffer to a buffer allocated by the NT kernel).
     OTOH this could be coming from the external module calling back into
     the kernel, which eventually causes the problem described above.

     Possibly as an extension of the problem that the krnlWaitSemaphore()
     call above works around, running two instances of cryptlib (e.g. two
     applications that use it) under NT4 can result in one of them hanging
     in the RegQueryValueEx() call.  This happens only under NT4 and is
     hard to reproduce in any consistent manner.

     One workaround that helps a bit is to read the registry as a remote
     (rather than local) registry, it's possible that the use of a network
     RPC call isolates the calling app from the problem in that whatever
     service handles the RPC is taking the hit and not affecting the
     calling app.  Since this would require another round of extensive
     testing to verify and the NT native API call is working fine, we'll
     stick with the native API call for now.

     Some versions of NT4 had a problem where the amount of data returned
     was mis-reported and would never settle down, because of this the code
     below includes a safety-catch that bails out after 10 attempts have
     been made, this results in no data being returned but at does ensure
     that the thread will terminate.

     In addition to these problems the code in RegQueryValueEx() that
     estimates the amount of memory required to return the performance
     counter information isn't very accurate (it's much worse than the
     "slightly-inaccurate" level that the MS docs warn about, it's usually
     wildly off) since it always returns a worst-case estimate which is
     usually nowhere near the actual amount required.  For example it may
     report that 128K of memory is required, but only return 64K of data.

     Even worse than the registry-based performance counters is the
     performance data helper (PDH) shim that tries to make the counters
     look like the old Win16 API (which is also used by Win95).  Under NT
     this can consume tens of MB of memory and huge amounts of CPU time
     while it gathers its data, and even running once can still consume
     about 1/2MB of memory */
  if (getenv ("GNUPG_RNDW32_NOPERF"))
    {
      static int shown;

      if (!shown)
        {
          shown = 1;
          log_info ("note: get performance data has been disabled\n");
        }
    }
  else
    {
      pPerfData = xmalloc (cbPerfData);
      for (iterations=0; iterations < 10; iterations++)
        {
          dwSize = cbPerfData;
          if ( debug_me )
            log_debug ("rndw32#slow_gatherer_nt: get perf data\n" );

          status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
                                    NULL, (LPBYTE) pPerfData, &dwSize);
          if (status == ERROR_SUCCESS)
            {
              if (!memcmp (pPerfData->Signature, L"PERF", 8))
                (*add) ( pPerfData, dwSize, requester );
              else
                log_debug ("rndw32: no PERF signature\n");
              break;
            }
          else if (status == ERROR_MORE_DATA)
            {
              cbPerfData += PERFORMANCE_BUFFER_STEP;
              pPerfData = xrealloc (pPerfData, cbPerfData);
            }
          else
            {
              static int been_here;

              /* Silence the error message.  In particular under Wine (as
                 of 2008) we would get swamped with such diagnotiscs.  One
                 such diagnotiscs should be enough.  */
              if (been_here != status)
                {
                  been_here = status;
                  log_debug ("rndw32: get performance data problem: ec=%ld\n",
                             status);
                }
              break;
            }
        }
      xfree (pPerfData);
    }

  /* Although this isn't documented in the Win32 API docs, it's necessary
     to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
     implicitly opened on the first call to RegQueryValueEx()).  If this
     isn't done then any system components which provide performance data
     can't be removed or changed while the handle remains active.  */
  RegCloseKey (HKEY_PERFORMANCE_DATA);
}


static void
slow_gatherer ( void (*add)(const void*, size_t, enum random_origins),
                enum random_origins requester )
{
  static int is_initialized = 0;
  static int is_workstation = 1;
  HANDLE hDevice;
  DWORD dwType, dwSize, dwResult;
  ULONG ulSize;
  int drive_no, status;
  int no_results = 0;
  void *buffer;

  if ( !is_initialized )
    {
      HKEY hKey;

      if ( debug_me )
        log_debug ("rndw32#slow_gatherer: init toolkit\n" );
      /* Find out whether this is an NT server or workstation if necessary */
      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
                        "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
                        0, KEY_READ, &hKey) == ERROR_SUCCESS)
        {
          BYTE szValue[32 + 8];
          dwSize = 32;

          if ( debug_me )
            log_debug ("rndw32#slow_gatherer: check product options\n" );

          status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
                                    szValue, &dwSize);
          if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT"))
            {
              /* Note: There are (at least) three cases for ProductType:
                 WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
                 NT Server acting as a Domain Controller.  */
              is_workstation = 0;
              if ( debug_me )
                log_debug ("rndw32: this is a NT server\n");
            }
          RegCloseKey (hKey);
        }

      /* The following are fixed for the lifetime of the process so we
         only add them once */
      /* readPnPData ();  - we have not implemented that.  */

      /* Initialize the NetAPI32 function pointers if necessary */
      hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
      if (hNetAPI32)
        {
          if (debug_me)
            log_debug ("rndw32#slow_gatherer: netapi32 loaded\n" );
          pNetStatisticsGet = (NETSTATISTICSGET)
            GetProcAddress (hNetAPI32, "NetStatisticsGet");
          pNetApiBufferSize = (NETAPIBUFFERSIZE)
            GetProcAddress (hNetAPI32, "NetApiBufferSize");
          pNetApiBufferFree = (NETAPIBUFFERFREE)
            GetProcAddress (hNetAPI32, "NetApiBufferFree");

          if (!pNetStatisticsGet || !pNetApiBufferSize || !pNetApiBufferFree)
            {
              FreeLibrary (hNetAPI32);
              hNetAPI32 = NULL;
              log_debug ("rndw32: No NETAPI found\n" );
            }
        }

      /* Initialize the NT kernel native API function pointers if necessary */
      hNTAPI = GetModuleHandle ("NTDll.dll");
      if (hNTAPI)
        {
          /* Get a pointer to the NT native information query functions */
          pNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)
            GetProcAddress (hNTAPI, "NtQuerySystemInformation");
          pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS)
            GetProcAddress (hNTAPI, "NtQueryInformationProcess");
          pNtPowerInformation = (NTPOWERINFORMATION)
            GetProcAddress(hNTAPI, "NtPowerInformation");

          if (!pNtQuerySystemInformation || !pNtQueryInformationProcess)
            hNTAPI = NULL;
        }


      is_initialized = 1;
    }

  read_system_rng ( add, requester );
  read_mbm_data ( add, requester );

  /* Get network statistics.    Note: Both NT Workstation and NT Server by
     default will be running both the workstation and server services.  The
     heuristic below is probably useful though on the assumption that the
     majority of the network traffic will be via the appropriate service.
     In any case the network statistics return almost no randomness.  */
  {
    LPBYTE lpBuffer;

    if (hNetAPI32
        && !pNetStatisticsGet (NULL,
                               is_workstation ? L"LanmanWorkstation" :
                               L"LanmanServer", 0, 0, &lpBuffer))
      {
        if ( debug_me )
          log_debug ("rndw32#slow_gatherer: get netstats\n" );
        pNetApiBufferSize (lpBuffer, &dwSize);
        (*add) ( lpBuffer, dwSize, requester );
        pNetApiBufferFree (lpBuffer);
      }
  }

  /* Get disk I/O statistics for all the hard drives.  100 is an
     arbitrary failsafe limit.  */
  for (drive_no = 0; drive_no < 100 ; drive_no++)
    {
      char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT + 8];
      char szDevice[50];

      /* Check whether we can access this device.  */
      snprintf (szDevice, sizeof szDevice, "\\\\.\\PhysicalDrive%d",
                drive_no);
      hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
                            NULL, OPEN_EXISTING, 0, NULL);
      if (hDevice == INVALID_HANDLE_VALUE)
        break; /* No more drives.  */

      /* Note: This only works if you have turned on the disk performance
         counters with 'diskperf -y'.  These counters are off by default. */
      dwSize = sizeof diskPerformance;
      if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
                           diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT,
                           &dwSize, NULL))
        {
          if ( debug_me )
            log_debug ("rndw32#slow_gatherer: iostat drive %d\n",
                       drive_no);
          (*add) (diskPerformance, dwSize, requester);
        }
      else
        {
          log_info ("NOTE: you should run 'diskperf -y' "
                    "to enable the disk statistics\n");
        }
      CloseHandle (hDevice);
    }

  /* In theory we should be using the Win32 performance query API to obtain
     unpredictable data from the system, however this is so unreliable (see
     the multiple sets of comments in registryPoll()) that it's too risky
     to rely on it except as a fallback in emergencies.  Instead, we rely
     mostly on the NT native API function NtQuerySystemInformation(), which
     has the dual advantages that it doesn't have as many (known) problems
     as the Win32 equivalent and that it doesn't access the data indirectly
     via pseudo-registry keys, which means that it's much faster.  Note
     that the Win32 equivalent actually works almost all of the time, the
     problem is that on one or two systems it can fail in strange ways that
     are never the same and can't be reproduced on any other system, which
     is why we use the native API here.  Microsoft officially documented
     this function in early 2003, so it'll be fairly safe to use.  */
  if ( !hNTAPI )
    {
      registry_poll (add, requester);
      return;
    }


  /* Scan the first 64 possible information types (we don't bother with
     increasing the buffer size as we do with the Win32 version of the
     performance data read, we may miss a few classes but it's no big deal).
     This scan typically yields around 20 pieces of data, there's nothing
     in the range 65...128 so chances are there won't be anything above
     there either.  */
  buffer = xmalloc (PERFORMANCE_BUFFER_SIZE);
  for (dwType = 0; dwType < 64; dwType++)
    {
      switch (dwType)
        {
          /* ID 17 = SystemObjectInformation hangs on some win2k systems.  */
        case 17:
          if (system_is_w2000)
            continue;
          break;

          /* Some information types are write-only (the IDs are shared with
             a set-information call), we skip these.  */
        case 26: case 27: case 38: case 46: case 47: case 48: case 52:
          continue;

          /* ID 53 = SystemSessionProcessInformation reads input from the
             output buffer, which has to contain a session ID and pointer
             to the actual buffer in which to store the session information.
             Because this isn't a standard query, we skip this.  */
        case  53:
          continue;
        }

      /* Query the info for this ID.  Some results (for example for
         ID = 6, SystemCallCounts) are only available in checked builds
         of the kernel.  A smaller subcless of results require that
         certain system config flags be set, for example
         SystemObjectInformation requires that the
         FLG_MAINTAIN_OBJECT_TYPELIST be set in NtGlobalFlags.  To avoid
         having to special-case all of these, we try reading each one and
         only use those for which we get a success status.  */
      dwResult = pNtQuerySystemInformation (dwType, buffer,
                                            PERFORMANCE_BUFFER_SIZE - 2048,
                                            &ulSize);
      if (dwResult != ERROR_SUCCESS)
        continue;

      /* Some calls (e.g. ID = 23, SystemProcessorStatistics, and ID = 24,
         SystemDpcInformation) incorrectly return a length of zero, so we
         manually adjust the length to the correct value.  */
      if ( !ulSize )
        {
          if (dwType == 23)
            ulSize = 6 * sizeof (ULONG);
          else if (dwType == 24)
            ulSize = 5 * sizeof (ULONG);
        }

      /* If we got some data back, add it to the entropy pool.  */
      if (ulSize > 0 && ulSize <= PERFORMANCE_BUFFER_SIZE - 2048)
        {
          if (debug_me)
            log_debug ("rndw32#slow_gatherer: %lu bytes from sysinfo %ld\n",
                       ulSize, dwType);
          (*add) (buffer, ulSize, requester);
          no_results++;
        }
    }

  /* Now we would do the same for the process information.  This
     call would rather ugly in that it requires an exact length
     match for the data returned, failing with a
     STATUS_INFO_LENGTH_MISMATCH error code (0xC0000004) if the
     length isn't an exact match.  It requires a compiler to handle
     complex nested structs, alignment issues, and so on, and
     without the headers in which the entries are declared it's
     almost impossible to do.  Thus we don't.  */


  /* Finally, do the same for the system power status information.  There
     are only a limited number of useful information types available so we
     restrict ourselves to the useful types.  In addition since this
     function doesn't return length information, we have to hardcode in
     length data.  */
  if (pNtPowerInformation)
    {
      static const struct { int type; int size; } powerInfo[] = {
        { 0, 128 },     /* SystemPowerPolicyAc */
        { 1, 128 },     /* SystemPowerPolicyDc */
        { 4, 64 },      /* SystemPowerCapabilities */
        { 5, 48 },      /* SystemBatteryState */
        { 11, 48 },     /* ProcessorInformation */
        { 12, 24 },     /* SystemPowerInformation */
        { -1, -1 }
      };
      int i;

      /* The 100 is a failsafe limit.  */
      for (i = 0; powerInfo[i].type != -1 && i < 100; i++ )
        {
          /* Query the info for this ID */
          dwResult = pNtPowerInformation (powerInfo[i].type, NULL, 0, buffer,
                                          PERFORMANCE_BUFFER_SIZE - 2048);
          if (dwResult != ERROR_SUCCESS)
            continue;
          if (debug_me)
            log_debug ("rndw32#slow_gatherer: %u bytes from powerinfo %d\n",
                       powerInfo[i].size, i);
          (*add) (buffer, powerInfo[i].size, requester);
          no_results++;
        }
      gcry_assert (i < 100);
    }
  xfree (buffer);

  /* We couldn't get enough results from the kernel, fall back to the
     somewhat troublesome registry poll.  */
  if (no_results < 15)
    registry_poll (add, requester);
}


int
_gcry_rndw32_gather_random (void (*add)(const void*, size_t,
                                        enum random_origins),
                            enum random_origins origin,
                            size_t length, int level )
{
  static int is_initialized;

  if (!level)
    return 0;

  /* We don't differentiate between level 1 and 2 here because there
     is no internal entropy pool as a scary resource.  It may all work
     slower, but because our entropy source will never block but
     deliver some not easy to measure entropy, we assume level 2.  */

  if (!is_initialized)
    {
      OSVERSIONINFO osvi = { sizeof( osvi ) };

      GetVersionEx( &osvi );
      if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
        log_fatal ("can only run on a Windows NT platform\n" );
      system_is_w2000 = (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0);
      init_system_rng ();
      is_initialized = 1;
    }

  if (debug_me)
    log_debug ("rndw32#gather_random: ori=%d len=%u lvl=%d\n",
               origin, (unsigned int)length, level );

  slow_gatherer (add, origin);

  return 0;
}



void
_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
                                             enum random_origins),
                                 enum random_origins origin)
{
  static int addedFixedItems = 0;

  if ( debug_me )
    log_debug ("rndw32#gather_random_fast: ori=%d\n", origin );

  /* Get various basic pieces of system information: Handle of active
     window, handle of window with mouse capture, handle of clipboard
     owner handle of start of clpboard viewer list, pseudohandle of
     current process, current process ID, pseudohandle of current
     thread, current thread ID, handle of desktop window, handle of
     window with keyboard focus, whether system queue has any events,
     cursor position for last message, 1 ms time for last message,
     handle of window with clipboard open, handle of process heap,
     handle of procs window station, types of events in input queue,
     and milliseconds since Windows was started.  */

  {
    byte buffer[20*sizeof(ulong)], *bufptr;

    bufptr = buffer;
#define ADD(f)  do { ulong along = (ulong)(f);                  \
                     memcpy (bufptr, &along, sizeof (along) );  \
                     bufptr += sizeof (along);                  \
                   } while (0)

    ADD ( GetActiveWindow ());
    ADD ( GetCapture ());
    ADD ( GetClipboardOwner ());
    ADD ( GetClipboardViewer ());
    ADD ( GetCurrentProcess ());
    ADD ( GetCurrentProcessId ());
    ADD ( GetCurrentThread ());
    ADD ( GetCurrentThreadId ());
    ADD ( GetDesktopWindow ());
    ADD ( GetFocus ());
    ADD ( GetInputState ());
    ADD ( GetMessagePos ());
    ADD ( GetMessageTime ());
    ADD ( GetOpenClipboardWindow ());
    ADD ( GetProcessHeap ());
    ADD ( GetProcessWindowStation ());
    ADD ( GetQueueStatus (QS_ALLEVENTS));
    ADD ( GetTickCount ());

    gcry_assert ( bufptr-buffer < sizeof (buffer) );
    (*add) ( buffer, bufptr-buffer, origin );
#undef ADD
  }

  /* Get multiword system information: Current caret position, current
     mouse cursor position.  */
  {
    POINT point;

    GetCaretPos (&point);
    (*add) ( &point, sizeof (point), origin );
    GetCursorPos (&point);
    (*add) ( &point, sizeof (point), origin );
  }

  /* Get percent of memory in use, bytes of physical memory, bytes of
     free physical memory, bytes in paging file, free bytes in paging
     file, user bytes of address space, and free user bytes.  */
  {
    MEMORYSTATUS memoryStatus;

    memoryStatus.dwLength = sizeof (MEMORYSTATUS);
    GlobalMemoryStatus (&memoryStatus);
    (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
  }

  /* Get thread and process creation time, exit time, time in kernel
     mode, and time in user mode in 100ns intervals.  */
  {
    HANDLE handle;
    FILETIME creationTime, exitTime, kernelTime, userTime;
    DWORD minimumWorkingSetSize, maximumWorkingSetSize;

    handle = GetCurrentThread ();
    GetThreadTimes (handle, &creationTime, &exitTime,
                    &kernelTime, &userTime);
    (*add) ( &creationTime, sizeof (creationTime), origin );
    (*add) ( &exitTime, sizeof (exitTime), origin );
    (*add) ( &kernelTime, sizeof (kernelTime), origin );
    (*add) ( &userTime, sizeof (userTime), origin );

    handle = GetCurrentProcess ();
    GetProcessTimes (handle, &creationTime, &exitTime,
                     &kernelTime, &userTime);
    (*add) ( &creationTime, sizeof (creationTime), origin );
    (*add) ( &exitTime, sizeof (exitTime), origin );
    (*add) ( &kernelTime, sizeof (kernelTime), origin );
    (*add) ( &userTime, sizeof (userTime), origin );

    /* Get the minimum and maximum working set size for the current
       process.  */
    GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
                              &maximumWorkingSetSize);
    (*add) ( &minimumWorkingSetSize,
             sizeof (minimumWorkingSetSize), origin );
    (*add) ( &maximumWorkingSetSize,
             sizeof (maximumWorkingSetSize), origin );
  }


  /* The following are fixed for the lifetime of the process so we only
   * add them once */
  if (!addedFixedItems)
    {
      STARTUPINFO startupInfo;

      /* Get name of desktop, console window title, new window
         position and size, window flags, and handles for stdin,
         stdout, and stderr.  */
      startupInfo.cb = sizeof (STARTUPINFO);
      GetStartupInfo (&startupInfo);
      (*add) ( &startupInfo, sizeof (STARTUPINFO), origin );
      addedFixedItems = 1;
    }

  /* The performance of QPC varies depending on the architecture it's
     running on and on the OS, the MS documentation is vague about the
     details because it varies so much.  Under Win9x/ME it reads the
     1.193180 MHz PIC timer.  Under NT/Win2K/XP it may or may not read the
     64-bit TSC depending on the HAL and assorted other circumstances,
     generally on machines with a uniprocessor HAL
     KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines
     with a multiprocessor or APIC HAL it uses the TSC (the exact time
     source is controlled by the HalpUse8254 flag in the kernel).  That
     choice of time sources is somewhat peculiar because on a
     multiprocessor machine it's theoretically possible to get completely
     different TSC readings depending on which CPU you're currently
     running on, while for uniprocessor machines it's not a problem.
     However, the kernel appears to synchronise the TSCs across CPUs at
     boot time (it resets the TSC as part of its system init), so this
     shouldn't really be a problem.  Under WinCE it's completely platform-
     dependant, if there's no hardware performance counter available, it
     uses the 1ms system timer.

     Another feature of the TSC (although it doesn't really affect us here)
     is that mobile CPUs will turn off the TSC when they idle, Pentiums
     will change the rate of the counter when they clock-throttle (to
     match the current CPU speed), and hyperthreading Pentiums will turn
     it off when both threads are idle (this more or less makes sense,
     since the CPU will be in the halted state and not executing any
     instructions to count).

     To make things unambiguous, we detect a CPU new enough to call RDTSC
     directly by checking for CPUID capabilities, and fall back to QPC if
     this isn't present.  */
#ifdef __GNUC__
/*   FIXME: We would need to implement the CPU feature tests first.  */
/*   if (cpu_has_feature_rdtsc) */
/*     { */
/*       uint32_t lo, hi; */
      /* We cannot use "=A", since this would use %rax on x86_64. */
/*       __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); */
      /* Ignore high 32 bits, hwich are >1s res.  */
/*       (*add) (&lo, 4, origin ); */
/*     } */
/*   else */
#endif /*!__GNUC__*/
    {
      LARGE_INTEGER performanceCount;

      if (QueryPerformanceCounter (&performanceCount))
        {
          if ( debug_me )
          log_debug ("rndw32#gather_random_fast: perf data\n");
          (*add) (&performanceCount, sizeof (performanceCount), origin);
        }
      else
        {
          /* Millisecond accuracy at best... */
          DWORD aword = GetTickCount ();
          (*add) (&aword, sizeof (aword), origin );
        }
    }


}
