[BUG FIX] Win32 Performance Counters

Keith Ray aphex@nullify.org
Fri May 17 00:50:02 2002


In cipher/rndw32.c, GnuPG attempts to gather physical disk performance counter
data for random number generation.  However, if the IOCTL_DISK_PERFORMANCE call
fails for any reason, GPG displays:

"NOTE: you should run 'diskperf -y' to enable the disk statistics"

I created a debug version of GnuPG and called GetLastError() and got:

"The data area passed to a system call is too small."

I did some investigating and found that the Win32 header files from Mingw32/CPD
are incorrect.  Both the LARGE_INTEGER and DISK_PERFORMANCE struct are smaller
than required.  Once these changes were made, I was able to produce a working
GnuPG that successfully called IOCTL_DISK_PERFORMANCE.  However, GCC gave the
following warning:

In file included from
/usr/local/lib/mingw32-cpd/lib/gcc-lib/i386--mingw32/2.95.2wk20010117/../../../../i386--mingw32/include/windows.h:48,
                 from rndw32.c:69:
/usr/local/lib/mingw32-cpd/lib/gcc-lib/i386--mingw32/2.95.2wk20010117/../../../../i386--mingw32/include/Windows32/Structures.h:1080:
warning: unnamed struct/union that defines no instances


mingw32-cpd/i386--mingw32/include/Windows32/Structures.h
--------------------------------------------------------

typedef struct _LARGE_INTEGER {
  DWORD LowPart;
  LONG  HighPart;
} LARGE_INTEGER, *PLARGE_INTEGER;

typedef struct _DISK_PERFORMANCE {
  LARGE_INTEGER BytesRead;
  LARGE_INTEGER BytesWritten;
  LARGE_INTEGER ReadTime;
  LARGE_INTEGER WriteTime;
  DWORD ReadCount;
  DWORD WriteCount;
  DWORD QueueDepth;
} DISK_PERFORMANCE ;


Microsoft Platform SDK\Include\WinIoCtl.h
-----------------------------------------

typedef struct _DISK_PERFORMANCE {
        LARGE_INTEGER BytesRead;
        LARGE_INTEGER BytesWritten;
        LARGE_INTEGER ReadTime;
        LARGE_INTEGER WriteTime;
        LARGE_INTEGER IdleTime;
        DWORD ReadCount;
        DWORD WriteCount;
        DWORD QueueDepth;
        DWORD SplitCount;
        LARGE_INTEGER QueryTime;
        DWORD   StorageDeviceNumber;
        WCHAR   StorageManagerName[8];
} DISK_PERFORMANCE, *PDISK_PERFORMANCE;


Microsoft Platform SDK\Include\WinNT.h
--------------------------------------

typedef union _LARGE_INTEGER {
    struct {
        DWORD LowPart;
        LONG HighPart;
    };
    struct {
        DWORD LowPart;
        LONG HighPart;
    } u;
    LONGLONG QuadPart;
} LARGE_INTEGER;