[racket] OpenEventLog in ffi
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
EVENTRECORD, but
> (define dwBytesToRead MAX_RECORD_BUFFER_SIZE)
> [...]
> (define bReadEventlog (ReadEventLogW hEventLog 
>                                     (bitwise-ior 
> EVENTLOG_SEQUENTIAL_READ                        EVENTLOG_BACKWARDS_READ)
>                                     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
corrupted.
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
                                   _HANDLE
                                   _DWORD
                                   _DWORD
                                   (m : (_ptr o _EVENTLOGRECORD))
                                   _DWORD
                                   (got : (_ptr o _DWORD))
                                   (needed : (_ptr o _DWORD))
                                   -> (r : _BOOL)
                                   -> (values r got needed)))
so that `ReadEventLogW' returns three results.