basicqbasicqb64

CreateDir throws exception in QB64


I have the following code that sometimes returns an error when trying to create a new directory. Sometimes when that directory doesn't exist, it throws an error and does not create the directory. I would like to know why?

DECLARE DYNAMIC LIBRARY "kernel32"
    FUNCTION CreateDirectoryA% (F$, X$)
    FUNCTION GetLastError& ()
END DECLARE
F$ = "TEMPX" + CHR$(0) ' new directory to create
x = CreateDirectoryA(F$, CHR$(0))
IF x = 0 THEN
    IF GetLastError = &H3E6 THEN
        PRINT "Invalid access to memory location."
    END IF
END IF

This code was written in QB64.


Solution

  • What you're passing as the lpSecurityAttributes parameter of CreateDirectoryA is a string of length 0; strings still have memory addresses, which means you're passing a non-null pointer. This is interpreted by CreateDirectoryA as a pointer to a SECURITY_ATTRIBUTES structure with its first byte set to 0. The rest of the bytes in the structure are memory you haven't initialized, meaning the structure's first field nLength on a little endian machine could be something like 0xFFFFFF00, which is 4294967040—an invalid size. The lpSecurityDescriptor field of that structure is presumably filled with bytes as well (possibly accessible by your program, but perhaps not), so this could be causing the issue as well.

    You can remedy this easily:

    ' X%& may also be written X AS _OFFSET.
    FUNCTION CreateDirectoryA% (F$, BYVAL X%&)
    
    ...
    
    x = CreateDirectoryA(F$, 0)
    

    This results in passing a NULL pointer properly. The BYVAL keyword is necessary, else you'll be passing a pointer to the _OFFSET value (because everything in QB64 is passed by pointer unless you use the BYVAL keyword; strings and user-defined types cannot be passed BYVAL).