Discussion:
Console : volume name displayed by "dir" is different than returned by GetVolumeInformation ?
(too old to reply)
R.Wieser
2022-01-31 12:31:34 UTC
Permalink
Hello all,

Inside an XPsp3 CMD.EXE console window :

I've just used 'GetVolumeInformation' function to retrieve a drives volume
name and noticed that it looks differently from when I did a "dir" for the
same drive.

The "dir" command returns an intended 0xFA (a small vertically-centered
dot), the GetVolumeInformation function returns a 0XB7 (single border left,
double border down).

I'm /guessing/ that some kind of characterset translation is performed
by/for the "dir" command. How can I have the same done to (the output of)
the GetVolumeInformation function ?

Regards,
Rudy Wieser
JJ
2022-02-01 02:41:17 UTC
Permalink
Post by R.Wieser
Hello all,
I've just used 'GetVolumeInformation' function to retrieve a drives volume
name and noticed that it looks differently from when I did a "dir" for the
same drive.
The "dir" command returns an intended 0xFA (a small vertically-centered
dot), the GetVolumeInformation function returns a 0XB7 (single border left,
double border down).
I'm /guessing/ that some kind of characterset translation is performed
by/for the "dir" command. How can I have the same done to (the output of)
the GetVolumeInformation function ?
Regards,
Rudy Wieser
The Middle Dot character's Unicode Codepoint is 0xB7 which is the same
character code for Windows (ANSI) code page. DIR generates character code
translated to OEM US code page 437, which is 0xFA.

If you switch to code page 1252 in CMD using `chcp 1252` then capture the
DIR output, it'll generate character code 0xB7 instead of 0xFA.
R.Wieser
2022-02-01 09:49:33 UTC
Permalink
JJ,
Post by JJ
The Middle Dot character's Unicode Codepoint is 0xB7 which is the same
character code for Windows (ANSI) code page. DIR generates character
code translated to OEM US code page 437, which is 0xFA.
Thanks for confirming my guess. :-)
Post by JJ
If you switch to code page 1252 in CMD using `chcp 1252` then capture
the DIR output, it'll generate character code 0xB7 instead of 0xFA.
I just wrote a "thanks, I'm going to try that", but realized that that
ofcourse affects all other console-based programs too, and only on my
current machine - neither of which is positive.

IOW, I'm going to see if I can find something that will either only change
the codepage for a single program (emulating what the DIR command seems to
be doing), or perhaps even a codepage translation for just that string.
Google/DDG, here I come :-)

Regards,
Rudy Wieser
JJ
2022-02-01 14:25:16 UTC
Permalink
Post by R.Wieser
IOW, I'm going to see if I can find something that will either only change
the codepage for a single program (emulating what the DIR command seems to
be doing), or perhaps even a codepage translation for just that string.
Google/DDG, here I come :-)
I use Microsoft AppLocale for that.

https://en.wikipedia.org/wiki/AppLocale
R.Wieser
2022-02-01 14:55:10 UTC
Permalink
JJ,
Post by JJ
I use Microsoft AppLocale for that.
Thanks. But I need my program set it for itself, and just for the 32...255
range.

Regards,
Rudy Wieser
R.Wieser
2022-02-01 14:51:19 UTC
Permalink
Post by R.Wieser
IOW, I'm going to see if I can find something that will either only change
the codepage for a single program
I found and tried SetConsoleOutputCP as well as SetConsoleCP, but neither
seems to affect the output I'm writing (to the STD_OUTPUT_HANDLE file).
And both seem to remain after my program terminates. :-|

Regards,
Rudy Wieser
Uwe Sieber
2022-02-02 10:56:31 UTC
Permalink
Post by R.Wieser
Post by R.Wieser
IOW, I'm going to see if I can find something that will either only change
the codepage for a single program
I found and tried SetConsoleOutputCP as well as SetConsoleCP, but neither
seems to affect the output I'm writing (to the STD_OUTPUT_HANDLE file).
And both seem to remain after my program terminates. :-|
Just make a unicode application and write the output by means of
WriteConsoleW(), which performs the translation to the console's
codepage which works without any losses if it is UTF-8 and no
bitmap font is used.

But if the output is redirected then WriteConsole fails and WriteFile
must be used. Here you write raw data and are reponsible to translate
the text to the desired format. I use GetACP() for WideCharToMultiByte.

m_OutputRedirected = ( GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) != FILE_TYPE_CHAR );
m_ErrorRedirected = ( GetFileType(GetStdHandle(STD_ERROR_HANDLE )) != FILE_TYPE_CHAR );

Or just assume redirection if WriteConsole fails ;-)


Uwe
R.Wieser
2022-02-02 16:33:50 UTC
Permalink
Uwe,
Post by Uwe Sieber
Just make a unicode application
Thanks, but no. I like ASCII too much to ditch it for a problem like this.
Post by Uwe Sieber
and write the output by means of WriteConsoleW()
The last time I looked that needed a console screen buffer. And while
playing with that I had to experience that those do not really work nicely
alongside of STD_OUTPUT_HANDLE file output (strange stuff happened).
Post by Uwe Sieber
m_OutputRedirected = ( GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) != FILE_TYPE_CHAR );
(Named) Pipes are also character devices ...
Post by Uwe Sieber
Or just assume redirection if WriteConsole fails ;-)
That sounds like something I would do. Its too damn hard to figure out if
a handle is redirected or not. Although MSDN mentiones GetConsoleMode I do
not see how (also, it has side effects when used on a pipe).

Thanks for the suggestion though.


I'm currently thinking of trying to use a MultiByteToWideChar,
WideCharToMultiByte pair to do the translation. Not elegant, but with
(seemingly) the absense of anything else it will have to do. :-\

Regards,
Rudy Wieser
Uwe Sieber
2022-02-03 08:14:54 UTC
Permalink
Post by R.Wieser
Post by Uwe Sieber
Just make a unicode application
Thanks, but no. I like ASCII too much to ditch it for a problem like this.
Then just use W functions here and there...
Post by R.Wieser
Post by Uwe Sieber
and write the output by means of WriteConsoleW()
The last time I looked that needed a console screen buffer. And while
playing with that I had to experience that those do not really work nicely
alongside of STD_OUTPUT_HANDLE file output (strange stuff happened).
No, WriteConsoleOutput needs console buffer, WriteConsole just a string buffer.
Post by R.Wieser
Post by Uwe Sieber
m_OutputRedirected = ( GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) != FILE_TYPE_CHAR );
(Named) Pipes are also character devices ...
Nope, they are FILE_TYPE_PIPE.
Post by R.Wieser
I'm currently thinking of trying to use a MultiByteToWideChar,
WideCharToMultiByte pair to do the translation. Not elegant, but with
(seemingly) the absense of anything else it will have to do. :-\
W function plus WriteConsoleW plus non-bitmap font plus codepage 65001 (UTF-8)
is the only way to avoid character translation losses.
Until you hit a FAT drive with non-ASCII charcters in the volume label (which
is OEM-CP on disk) written under a dfferent OEM-CP than the current one :-)

Uwe
R.Wieser
2022-02-03 10:50:44 UTC
Permalink
Uwe,
Post by Uwe Sieber
No, WriteConsoleOutput needs console buffer, WriteConsole just a string buffer.
I'm afraid MS begs to differ :

https://docs.microsoft.com/en-us/windows/console/writeconsole

"hConsoleOutput [in]
A handle to the console screen buffer."
Post by Uwe Sieber
Post by R.Wieser
Post by Uwe Sieber
m_OutputRedirected = ( GetFileType(GetStdHandle(STD_OUTPUT_HANDLE))
!= FILE_TYPE_CHAR );
(Named) Pipes are also character devices ...
Nope, they are FILE_TYPE_PIPE.
My apologies, I was (somehow) looking at GetConsoleMode.

And although I wondered about a redirected-to-another-programs StdIn, a
quick test showed that that also returns the "pipe" type.
Post by Uwe Sieber
W function plus WriteConsoleW plus non-bitmap font plus codepage 65001
(UTF-8) is the only way to avoid character translation losses.
That does limit my options a bit. :-|
Post by Uwe Sieber
Until you hit a FAT drive with non-ASCII charcters in the volume label
(which is OEM-CP on disk) written under a dfferent OEM-CP than the current
one :-)
At the time I created that volume label (first letter of my christian name,
vertically centered dot, family name - on an USB stick) I already wondered
how long it would take before some kind of a problem with it would pop up
...

Although it didn't for a decade or so I think I should re-think the wisdom
of it. :-)

Thanks for the information.

Regards,
Rudy Wieser
Uwe Sieber
2022-02-04 08:09:14 UTC
Permalink
Post by R.Wieser
Post by Uwe Sieber
No, WriteConsoleOutput needs console buffer, WriteConsole just a string buffer.
https://docs.microsoft.com/en-us/windows/console/writeconsole
"hConsoleOutput [in]
A handle to the console screen buffer."
I thought you talk about the buffer with the characters to write...

About the handle:
GetStdHandle(STD_OUTPUT_HANDLE) is the handle to the current console
screen buffer and can be used with WriteConsole and WriteConsoleOutput.


Uwe
R.Wieser
2022-02-04 13:51:18 UTC
Permalink
Uwe,
Post by Uwe Sieber
I thought you talk about the buffer with the characters to write...
:-) And I was thinking that that is normally referred to as "a string" ...

I on my side did not recognise that "the console screen buffer" is not just
an array of bytes.
Post by Uwe Sieber
GetStdHandle(STD_OUTPUT_HANDLE) is the handle to the current console
screen buffer and can be used with WriteConsole and WriteConsoleOutput.
Thanks. Having to rely on the MS docs for most of what I do I surely miss
(in more than one sense of the word) details like that. :-\

Regards,
Rudy Wieser

R.Wieser
2022-02-04 10:35:19 UTC
Permalink
Uwe,
Post by R.Wieser
https://docs.microsoft.com/en-us/windows/console/writeconsole
"hConsoleOutput [in]
A handle to the console screen buffer."
I thought "what the heck, the program can only crash" and just now tried
providing it the StdOut handle. Unexpected (by me) I got output on the
screen *and* I could use WriteFile to the same StdOut handle without it
becoming a mess.

And oh yeah, it gave me the output I needed too (regardless of using the W
or A version).

IOW, I owe you another thanks.

As for MS, I guess its another example of how hard it is to write good
documentation. :-\

Regards,
Rudy Wieser
Loading...