(CC'd vm-dev)
On Mon, Aug 24, 2015 at 12:09 AM, Nicolai Hess nicolaihess@web.de wrote:
And If you want to review the changes:
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.
Also, anyone know if the concern "BIG WARNING about the return value and the `cbMultiByte` parameter" expressed near the end of [3] is relevant?
[1] ../pharo-vm/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c [2] ../pharo-vm/mc/VMMaker.oscog.package/FilePlugin.class/instance/primitiveFileDelete.st [3] https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072(v=vs.85).a...
On 24 Aug 2015, at 4:59 , Ben Coman btc@openInWorld.com wrote:
(CC'd vm-dev)
On Mon, Aug 24, 2015 at 12:09 AM, Nicolai Hess nicolaihess@web.de wrote:
And If you want to review the changes:
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
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-long-filename
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
On Mon, Aug 24, 2015 at 11:44 PM, Henrik Johansen < henrik.s.johansen@veloxit.no> wrote:
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 wrote:
(CC'd vm-dev)
On Mon, Aug 24, 2015 at 12:09 AM, Nicolai Hess nicolaihess@web.de wrote:
And If you want to review the changes:
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;\
doh! I was looking for that and didn't recognise it. Thanks Henry.
vm-dev@lists.squeakfoundation.org