1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Questions about @winapi/@capi

Discussion in 'Support' started by Steve Fabian, Feb 14, 2012.

  1. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    1/ When the BUFFER keyword is used (so TCC would provide a buffer in which the function can return a string),
    - is it necessary to specify the size of the buffer, or does TCC automatically provide it to the called function?
    - if the buffer size must be specified in the TCC command using @WINAPI, what is the maximum size?

    2/ Some APIs fill the buffer with data structured in the manner of environment variable storage, i.e., multiple individual strings, each terminated with a NUL character, with an empty string representing the end of the list. TCC users can only access the first string of the result, because its NUL terminator cuts off access. How can we access the subsequent strings? Possible methods I see:
    - spread the results into an array (undoubtedly requires significant TCC enhancement)
    - put the result into a binary buffer. This might be possible by passing the address and size of an already allocated binary buffer to the API, but I cannot find TCC syntax to make this possible.

    BTW, the HELP lines displaying the syntax of @CAPI and of @WINAPI have an unmatched left bracket [ where the choices of parameter formats to be passed to the API are shown, the list of choices is not closed, and there is no indication of repeatability. It apparently assumes that only professional programmers will try to use these functions and their mental parsers are DWIM.
     
  2. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,952
    Likes Received:
    30
    1. No, TCC does not require you to specify the buffer size though the API you're calling may require it (often does) as one of it's arguments. Everything after @WINAPI's "function" should be arguments to that function. [Rex, how big a buffer is passed?]

    ... don't know about 2.
     
  3. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    The QueryDosDevice function is one which requires a buffer where it returns one or more NUL-terminated strings. The "IsSubst" function variants proposed in another thread all used the string literal BUFFER as described in the @WINAPI help for the TCC supplied buffer, and the number 260 as its size. I tried the function without specifying BUFFER's size, and it worked - but I don't know if it might have corrupted some data storage areas, esp. when I used the literal string NULL to indicate that I want a list of ALL devices. However, if BUFFER is at least 260 characters, the longest list would have only 27 elements, the first 26 consisting of a letter, a colon, and a NUL, the last just a NUL, not requiring a buffer bigger than 79 characters, so I don't expect that there would have been an overflow...
     
  4. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,952
    Likes Received:
    30
    I used 260 out of habit ... because that's "MAX_PATH" and I figured it would be good enough. Seeing that QDD() returns paths in the "\??\" format, I suppose it's possible that MAX_PATH might not be enough (because paths in that format can be huge). I suspect the buffer TCC actually supplies is much bigger than that (TCC uses huge buffers for almost everything). In any event, APIs that ask for a buffer size are smart enough not to write past that point so there won't be corruption unless you specify a buffer size larger than TCC actually provides (which, as I said, is probably pretty big).
     
  5. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    1,190
    Likes Received:
    11
    Since QDD requires size as one of its arguments, I suspect that the API ended up using whatever happened to be on the stack at that location. Which was probably a huge number (return address perhaps?). But as long as the actual output is smaller than the true buffer size, you'd never have noticed.
     
  6. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,860
    Likes Received:
    83
    No. TCC uses a buffer size equivalent to the maximum argument size.

    You cannot. (And nobody's ever asked for it.)

    Nobody but professional programmers should be using @WINAPI / @CAPI. There are at least a couple dozen Windows APIs that will cheerfully obliterate your entire system with a single bad argument. (It would be safer for me to mail every user a grenade and hope that they're smart enough not to pull the pin and stuff it in their shorts, than to encourage widespread use of @WINAPI.)
     
  7. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    I know I did not previously ask for it because I was always going through TCC features to obtain all information, without tunneling through to Windows internals. Now that I have become interested, and I realize some APIs return information is such awkward manner, I am asking a means to overcome this limitation. As far as I can tell allowing the name and size of an allocated binary buffer to be passed to the API through the @WINAPI/@CAPI call would be a 100% backward compatible enhancement, and my guess is would not tax the parser too much, e.g., a new keyword in place of BUFFER, BINARYBUFFER=handle would do the job.
     
  8. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,860
    Likes Received:
    83
    It would require a substantial parser rewrite (and a new golden opportunity for users to crash TCC by erroneously specifying a multiple argument buffer for APIs that don't support it).

    If you want it, you know where to suggest it ...
     
  9. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    680
    Likes Received:
    8
    Hello Steve,
    Are you looking to do something similar to what AutoHotKey does? (DllCall, VarSetCapacity, RegisterCallback)

    Joe
     

Share This Page