/* rndw32.c  -  W32 entropy gatherer
 * Copyright (C) 1999, 2000, 2002, 2003, 2007 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 <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 nonexistant 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 */
  pPerfData = gcry_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 = gcry_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;
        }
    }
  gcry_free (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 = gcry_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);
    }
  gcry_free (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 );
        }
    }


}
