# [plt-scheme] String as output parameter of FFI call to W32 API GetLogicalDriveStringsW?

 From: Andrea Girotto (andrea.girotto at gmail.com) Date: Mon Feb 1 16:41:04 EST 2010 Previous message: [plt-scheme] [ANN] MrEd Designer 2.2 Next message: [plt-scheme] String as output parameter of FFI call to W32 API GetLogicalDriveStringsW? Messages sorted by: [date] [thread] [subject] [author]

```Hello,
I have a problem calling via FFI a Windows API function:
GetLogicalDrivesStringsW.

First of all, if I write:

#lang scheme
(require scheme/foreign)
(unsafe!)

(define kernel32 (ffi-lib "kernel32"))

(define get-logical-drive
(get-ffi-obj "GetLogicalDrives" kernel32
(_fun #:abi 'stdcall -> _uint32)
(lambda () (error 'kernel32 "Missing GetLogicalDrives")) ) )

(let ((drives (get-logical-drive)))
(display drives)
(display #\tab)
(display (number->string drives 2))(newline) )

262157  1000000000000001101

So it is telling me that there are A:, C:, D: and S: (and FFI is
working! :-)). That's correct, and I have the same answer with:

> (display (filesystem-root-list))(newline)
(C:\ D:\ S:\)

(the disk A: is missing because, in my opinion, the
"filesystem_root_list" function in src/mzscheme/src/file.c is checking
it with the "GetDiskFreeSpace" and there's absolutely no floppy in the
system...).

Now I need to get the same information in another way (...long story:
at the end of this path I will enumerate the USB sticks connected to
the computer, that is a relatively simple task with Linux, but such an
incredible complex task with Windows API, maybe it's only me and my
inexperience with Windows...):

(define get-logical-drive-strings-w
(get-ffi-obj "GetLogicalDriveStringsW" kernel32
(_fun #:abi 'stdcall
_uint32
_string
-> _uint32)
(lambda () (error 'kernel32 "Missing
GetLogicalDriveStrings")) ) )

(define get-logical-drive-strings
(let* ((n 128)
(s (make-string n #\~)))
(display (get-logical-drive-strings-w 128 s))(newline)
(display s)(newline)
(display (string->list s))(newline) ) )

I'm filling 128 chars with the "~" character before calling the
GetLogicalDriveStringsW.
This Windows API should return the number of characters written in the

16
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~)

The "16" number is the GetLogicaDriveStringsW that it is telling me
having written 16 characters...
But in the string there is only the sequence of "~" that I used to
initialize it...

My suspect :-) is that I cannot call a FFI function using a Scheme
string as output parameter.

BTW: the "filesystem_root_list" function in src/mzscheme/src/file.c is
calling "GetLogicalDriveStrings" to list the filesystems' roots. I
think that "GetLogicalDriveStrings" is a C/C++ macro of
"GetLogicalDriveStringsW" or "GetLogicalDriveStringsA", because the
first one is triggering the error message of "get-ffi-obj", the others
two are not...

So how can I pass a string as output parameter (to be filled from