On 24 Aug 2015, at 5:19 , Henrik Johansen <henrik.s.johansen@veloxit.no> wrote:
On 24 Aug 2015, at 4:59 , Ben Coman <btc@openInWorld.com <mailto:btc@openInWorld.com>> wrote:
(CC'd vm-dev)
On Mon, Aug 24, 2015 at 12:09 AM, Nicolai Hess <nicolaihess@web.de <mailto:nicolaihess@web.de>> wrote:
And If you want to review the changes:
https://github.com/nicolaihess/pharo-vm/compare/master...nicolaihess:win-lon... <https://github.com/nicolaihess/pharo-vm/compare/master...nicolaihess:win-lon...>
I don't have a Windows machine to test on, but I perused the changes. one spelling defect ../platforms/win32/vm/sqWin32.h, line 452 "functiosn"
Now my curiosity is aroused regarding sqFileDeleteNameSize() in [1]. Where does its parameter "char* fileNameIndex" get its null termination? I can only guess maybe the following definition in primitiveFileDelete.st [2] <var: 'nameIndex' type: 'char *'> automatically appends a null to the Smalltalk string. My understanding is that the Smalltalk string's internal representation is not null terminated.
I ask since the sqFileDeleteNameSize()'s comment "convert the file name into a null-terminated C string" indicates the null is added by MultiByteToWideChar(), but [3] indicates that is not true -- that the output of MultiByteToWideChar() is only null terminated if the input is null terminated.
That's not what 3 indicates, the way I read it: "cbMultiByte [in] Size, in bytes, of the string indicated by the lpMultiByteStr parameter. Alternatively, this parameter can be set to -1 if the string is null-terminated. " "cchWideChar [in] Size, in characters, of the buffer indicated by lpWideCharStr. If this value is 0, the function returns the required buffer size, in characters, including any terminating null character"
So we first make a call using cbMultiByte > 0 and cchWideChar = 0, which then returns the size of null-terminated WCHAR-buffer needed to hold the conversion of non-null terminated (but sized) parameter. (sz = size) Then create that buffer, assign it to win32Path, and convert into it the CONVERT_MULTIBYTE_TO_WIDECHAR_PATH macro.
The Win APIs are written in a way that they seldom (never?) allocate memory, instead you'll see this pattern of "call me once with size = NULL to get the required size, then allocate and call me again with the actual pointer/size"
Cheers, Henry
And I guess I would be wrong, reading a bit further: "MultiByteToWideChar does not null-terminate an output string if the input string length is explicitly specified without a terminating null character. To null-terminate an output string for this function, the application should pass in -1 or explicitly count the terminating null character for the input string." It is handled in the macro though, which adds the null terminator: buffer = (WCHAR*)malloc((size+ LONG_PATH_PREFIX_SIZE +1)*sizeof(WCHAR));\ buffer[size + 4] = 0;\ Cheers,Henry