[racket] OpenEventLog in ffi

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon Nov 26 21:00:31 EST 2012

At Tue, 27 Nov 2012 02:34:58 +0100, heraklea at gmx.de wrote:
> (define-advapi ReadEventLogW (_fun #:abi winapi
>                                   _HANDLE
>                                   _DWORD
>                                   _DWORD
>                                   (m : (_ptr o _EVENTLOGRECORD))
>                                   _DWORD
>                                   (type : (_ptr o _DWORD))
>                                   (type : (_ptr o _DWORD))
>                                   -> (r : _BOOL)))

The `(m : (_ptr o _EVENTLOGRECORD))' allocates space for a single

> (define dwBytesToRead MAX_RECORD_BUFFER_SIZE)
> [...]
> (define bReadEventlog (ReadEventLogW hEventLog 
>                                     (bitwise-ior 
>                                     0
>                                     dwBytesToRead
>                                     ))

claims that MAX_RECORD_BUFFER_SIZE space is available. My guess is that
ReadEventLogW tries return multiple records and thus overflows the
allocated buffer, which corrupts memory.

> I get this error in the last define:
> ptr-ref: contract violation
>   expected: cpointer?
>   given: #???
>   argument position: 1st
>   other arguments...:
>    #<ctype>

"#???" is a kind of nonsense that Racket prints when memory is

Probably you want to declare `ReadEventLogW' to take a `_pointer' as
the fourth argument, explicitly allocate an array of `_EVENTLOGRECORD'
to pass as that argument, and pass a fifth argument that is the size of
your explicitly allocated memory.

Your `(type : (_ptr o _DWORD))' arguments seem fine, except that `_fun'
shouldn't let you bind `type' twice! If you need those results, add an
extra `->', like this:

 (define-advapi ReadEventLogW (_fun #:abi winapi
                                   (m : (_ptr o _EVENTLOGRECORD))
                                   (got : (_ptr o _DWORD))
                                   (needed : (_ptr o _DWORD))
                                   -> (r : _BOOL)
                                   -> (values r got needed)))

so that `ReadEventLogW' returns three results.

Posted on the users mailing list.