Page 1 of 2

MASSIVE XP_SP1 BUG [corrupted stdout affects all *.EXE] !

Posted: 14 Feb 2012 14:27
by Ed Dyreen
something like

Code: Select all

1> "file" wmic.EXE path WIN32_USERACCOUNT get Name
and reading it back in

Code: Select all

for /f "usebackq delims=" %%? in ( "file" ) do set "$name=%%?" &echo.$name=!$name!_
gives something like

Code: Select all

_name=HelpAssistant
this makes me believe the result of wmic produces a carriage return at the end instead of CR LF.
When doing something like this, it seems to be fixed

Code: Select all

echo.$name=!$name:~0,-1!_
However I want to avoid having to fix it, I don't want the problem to show in the first place.
I also use this command but that doesn't fix it

Code: Select all

> "%%~a" type "%%~b" &> "%%~b" type "%%~a" %=          converts to ASCII =%
That's weirdness, any ideas ?

Re: wmic write/read weirdness ?!

Posted: 14 Feb 2012 15:09
by aGerman
The output of WMIC is unicode. TYPE can convert it to ASCII.

Regards
aGerman

Re: wmic write/read weirdness ?!

Posted: 14 Feb 2012 17:05
by Ed Dyreen
'
I'll try again :)

Code: Select all

@echo off

start "wmic.EXE" /i /wait /high /min "!comspec!" /c 1^> "workFile1.TMP" 2^> "workFile2.TMP" wmic.EXE path WIN32_USERACCOUNT get Name

for /f "usebackq skip=1 delims=!$cr!!$cr!" %%? in ( "workFile1.TMP" ) do set "$name=%%?"
echo.$name=!$name!_

for /f "usebackq skip=1 delims=%$cr%%$cr%" %%? in ( "workFile1.TMP" ) do set "$name=%%?"
echo.$name=!$name!_

for /f "usebackq skip=1 delims=" %%? in ( "workFile1.TMP" ) do set "$name=%%?"
echo.$name=!$name!_

for /f "usebackq skip=1 tokens=*" %%? in ( "workFile1.TMP" ) do set "$name=%%?"
echo.$name=!$name!_

> "workFile2.TMP" type "workFile1.TMP"

for /f "usebackq skip=1 delims=" %%? in ( "workFile2.TMP" ) do set "$name=%%?"
echo.$name=!$name!_

echo.$name=!$name:~0,-1!_

pause

Code: Select all

_name=SUPPORT_388945a0
_name=SUPPORT_388945a0
_name=SUPPORT_388945a0
_name=SUPPORT_388945a0
_name=SUPPORT_388945a0
$name=SUPPORT_388945a0  _

Druk op een toets om door te gaan. . .
It works if I strip of the last character from the variable which must be a carriage return not :?:
Was wondering whether I could use some delims or eol of the for so I wouldn't need to strip it of in the first place.
The type command converts to ascii but it has no effect on the carriage return. :roll:

ps: I need usebackq cause the path may contain spaces.

Re: wmic write/read weirdness ?!

Posted: 14 Feb 2012 17:41
by aGerman
If you use the FOR /F loop with an unicode text the line break is missinterpreted. It reads <cr><nul><lf><nul>.
I guess <nul> is skipped and <cr> is removed in this case (not sure, Dave or jeb could provide a better explanation :wink:).
You could process the TYPE command directly inside of the loop or convert the output-file more or less "on-the-fly"

Code: Select all

>"file.txt" (wmic /output:temp.txt path WIN32_USERACCOUNT get Name &type temp.txt &del temp.txt)

... but that needs a temporary file.

Regards
aGerman

Re: wmic write/read weirdness ?!

Posted: 14 Feb 2012 17:45
by Liviu
Can't really help here since it works as expected under my xp.sp3 (after converting the UTF-16LE file to plain text, that is). But, just curious, what's your Windows version and 32/64 bitness?
Ed Dyreen wrote:

Code: Select all

for /f "usebackq skip=1 delims=" %%? in ( "workFile1.TMP" ) do set "$name=%%?"
echo.$name=!$name!_

Code: Select all

_name=SUPPORT_388945a0

That looks like a 'for' loop reading a UTF-16LE file, which would be quite interesting on its own.

Liviu

Re: wmic write/read weirdness ?!

Posted: 14 Feb 2012 17:48
by aGerman
Liviu wrote:That looks like a 'for' loop reading a UTF-16LE file, which would be quite interesting on its own.

Exactly what I tried to explain :wink:

Regards
aGerman

Re: wmic write/read weirdness ?!

Posted: 14 Feb 2012 18:15
by Ed Dyreen
'
[edit] I prove myself wrong in the following posts !
Liviu wrote:Can't really help here since it works as expected under my xp.sp3 (after converting the UTF-16LE file to plain text, that is). But, just curious, what's your Windows version and 32/64 bitness?
This is XPPro32x86 SP1 nl (netherlands dutch region 0413=nl codepage 850), but I'm 100% sure it behaves like that in SP0 to SP3, so nothing to do with versions/builds.

Code: Select all

@echo off

start "wmic.EXE" /i /wait /high /min "!comspec!" /c 1^> "workFile1.TMP" 2^> "workFile2.TMP" wmic.EXE path WIN32_USERACCOUNT get Name

for /f "usebackq delims=%$SUB%" %%? in ( "workFile1.TMP" ) do echo.?=%%?_

copy/y/a "workFile1.TMP" "workFile2.TMP"
for /f "usebackq delims=" %%? in ( "workFile2.TMP" ) do echo.?=%%?_

copy/y/b "workFile1.TMP" "workFile3.TMP"
for /f "usebackq delims=" %%? in ( "workFile3.TMP" ) do echo.?=%%?_

pause

Code: Select all

_=Name
_=**removed**
_=HelpAssistant
_=SUPPORT_388945a0
        1 bestand(en) gekopieerd.
_=Name
_=**removed**
_=HelpAssistant
_=SUPPORT_388945a0
?=→_
        1 bestand(en) gekopieerd.
_=Name
_=**removed**
_=HelpAssistant
_=SUPPORT_388945a0

Druk op een toets om door te gaan. . .
I believe something with ascii, unicode, codepage or OS language stuff ??
I'm not good at that, I get confused :evil:

Re: wmic write/read weirdness ?!

Posted: 14 Feb 2012 18:22
by Liviu
aGerman wrote:Exactly what I tried to explain :wink:

Indeed. I am still curious about Ed's:
- implied cmd switches (guess there must be a /v:on, maybe others);
- external definitions (though I assume !cr!, !lf! are the expected controls);
- output of the code if '$name' is cleared before each 'for'.

FWIW what I am getting here (xp sp3 32b) is...

Code: Select all

$name=_
$name=_
$name=_
$name=_
$name=SUPPORT_388945a0  _
$name=SUPPORT_388945a0 _
...which is what I'd have expected - nothing from the UTF-16LE file, full line text from the 8-bit file.

I reckon CRs may be mis-parsed in command-return 'for' loops, such as Jeb's at http://stackoverflow.com/questions/8099411/redirect-output-of-batch-command-to-an-if-statement-and-string-error. But I still don't see stray CRs at the end of lines in the redirected TMP files.

Liviu

P.S. Just read Ed's followup above while posting my reply. One question at least still stands - does clearing $name before each loop make a difference? I don't see how the first 'for' loop could fill in $name off a UTF-16LE file, and would want to eliminate the possibility that what's echoed is a leftover from some previous assignment.

Re: wmic write/read weirdness ?!

Posted: 15 Feb 2012 00:50
by Ed Dyreen
'
I run this batch on two different pc's and get two different results :!:

Code: Select all

@echo off
start "wmic.EXE" /i /wait /high /min "%comspec%" /c 1^> "workFile1.TMP" wmic.EXE path WIN32_USERACCOUNT get Name

> "workFile2.TMP" type "workFile1.TMP"
> "workFile1.TMP" type "workFile2.TMP"

for /f "usebackq delims=" %%? in ( "workFile1.TMP" ) do echo.?=%%?_
PC 1 = WinXPPro32x86 Service Pack 2

Code: Select all

?=Name              _
...
?=HelpAssistant     _
?=SUPPORT_388945a0  _
Druk op een toets om door te gaan. . .
PC 2 = WinXPPro32x86 Service Pack 1

Code: Select all

_=Name
...
_=HelpAssistant
_=SUPPORT_388945a0
Druk op een toets om door te gaan. . .
I then look whether the output files are somehow different and yes they are :!:

Code: Select all

@echo off
for /f "usebackq delims=" %%? in ( "workFilePC1.TMP" ) do echo.?=%%?_
for /f "usebackq delims=" %%? in ( "workFilePC2.TMP" ) do echo.?=%%?_
pause
exit

Code: Select all

?=Name              _
...
?=HelpAssistant     _
?=SUPPORT_388945a0  _
_=Name
...
_=HelpAssistant
_=SUPPORT_388945a0
Druk op een toets om door te gaan. . .
workFilePC1.TMP

Code: Select all

// Generated by Hackman Hex Editor 8.0 pro
// workFilePC1.TMP - Starting offset: 0000:0000

0000:0000  4E 61 6D 65 20 20 20 20 20 20 20 20 20 20 20 20
0000:0010  20 20 0D 0A 48 65 6C 70 41 73 73 69 73 74 61 6E
0000:0020  74 20 20 20 20 20 0D 0A 53 55 50 50 4F 52 54 5F
0000:0030  33 38 38 39 34 35 61 30 20 20 0D 0A
workFilePC2.TMP

Code: Select all

// Generated by Hackman Hex Editor 8.0 pro
// workFilePC2.TMP - Starting offset: 0000:0000

0000:0000  4E 61 6D 65 20 20 20 20 20 20 20 20 20 20 20 20
0000:0010  20 20 0D 0D 0A 48 65 6C 70 41 73 73 69 73 74 61
0000:0020  6E 74 20 20 20 20 20 0D 0D 0A 53 55 50 50 4F 52
0000:0030  54 5F 33 38 38 39 34 35 61 30 20 20 0D 0D 0A 0D
0000:0040  0A 0D 0A
So the problem seems to be inside wmic's output :?

Code: Select all

0D 0D 0A
So the solution is to change every 0D 0D 0A into 0D 0A, translated
The solution is to change every <CR><CR><LF> to <CR><LF>

Thanks for the link, but I already figure that out, 0,-1 :)
http://stackoverflow.com/questions/8099 ... ring-error

Re: wmic write/read weirdness ?!

Posted: 15 Feb 2012 10:18
by Ed Dyreen
'
GOTCHA :mrgreen:

Yes aGerman you are right the type does converts to ascii, but it also takes the misformatted output from the wmic command !
wmic has issues on XP SP1 release, since wmic should never output a carriage return,
The following is safe, always.

Code: Select all

@echo off &setlocal disableDelayedExpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "$cr=%%a"
setlocal enableDelayedExpansion
echo.$cr failed !$cr!$cr succes

start "wmic.EXE" /i /wait /high /min "%comspec%" /c 1^> "workFile1.TMP" wmic.EXE path WIN32_USERACCOUNT get Name

> "workFile.TMP" type "workFile1.TMP"

for /f "usebackq delims=" %%? in ( "workFile.TMP" ) do echo.?=%%?_

for %%r in ("!$cr!") do for /f "usebackq delims=" %%? in ( "workFile.TMP" ) do set "$=%%?" &set "$=!$:%%~r=!" &echo.$=!$!_

pause
exit

Code: Select all

Microsoft Windows XP [versie 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

$cr succes
_=Name
...
_=HelpAssistant
_=SUPPORT_388945a0
$=Name              _
...
$=HelpAssistant     _
$=SUPPORT_388945a0  _
Druk op een toets om door te gaan. . .
I suggest NOT using the 0,-1 solution posted at the stack that overflow, for the obvious reason that it strips the last character, regardless :!:

ps: some people may wonder, why not just catch the output of wmic inside a for ?
If wmic were to crash/hang ( which happens more often then I'd like ) the script would lockup.


Regards, and thanks for helpin 8)

Re: [BUGFIX XP SP1] wmic corrupted stdout

Posted: 15 Feb 2012 14:42
by Ed Dyreen
'
I make another shocking discovery that may explain the weird behavior.
On my XP service pack 1 wmic produces output in ANSI
On my XP service pack 2 wmic produces output in unicode

I looked at the wmic /output switch hoping to be able to find some mode switch but it isn't there.
How on earth is that possible, I thought wmic ALWAYS output in unicode :shock: :?:

Re: [BUGFIX XP SP1] wmic corrupted stdout

Posted: 15 Feb 2012 15:53
by Liviu
Ed Dyreen wrote:I make another shocking discovery that may explain the weird behavior.
On my XP service pack 1 wmic produces output in ANSI
On my XP service pack 2 wmic produces output in unicode

Well... Sp1 is about 10 years old. XP has had two massive service packs since, plus countless updates. I am shocked that you'd find an Sp1 bug "shocking" ;-)

FWIW the Sp3 wmic.exe I have here is v5.1.2600.5512 and outputs Unicode with no double CRs or CR-CR-LF sequences.

Liviu

Re: [BUGFIX XP SP1] wmic corrupted stdout

Posted: 15 Feb 2012 16:29
by alan_b
Since XP with SP1 is "uncharted territory" it may be worth trying MORE instead of TYPE.
Since finding a spot of unicode in a text file I now use MORE to give text that CMD.EXE can manipulate.

Re: [BUGFIX XP SP1] wmic corrupted stdout

Posted: 15 Feb 2012 16:54
by Ed Dyreen
'
Didn't work, more preserves the carriage return :|

Code: Select all

start "wmic.EXE" /i /wait /high /min "%comspec%" /c 1^> "workFile1.TMP" wmic.EXE path WIN32_USERACCOUNT get Name

more "workFile1.TMP" >"workFile2.TMP"

type "workFile2.TMP"

Code: Select all

0D 0D 0A
<CR><CR><LF>
No worry, I solve it already in my above post 8)

Re: [BUGFIX XP SP1] wmic corrupted stdout

Posted: 27 Feb 2012 08:38
by Ed Dyreen
'
It turns out this is not a wmic bug but an XP Service Pack 1 general bug :!:

The bugfix is a real performance hit, thanks alot MS, really thanks :evil: http://www.freebsd.org/

Code: Select all

for %%r in ( "!$cr!" ) do for /f "skip=4 delims=" %%? in (

   '"!$scriptHost.fullPath!\SUPPORT\ResChangeCon\ResChangeCon.EXE" -listmodes'

) do    set "$=%%?" &set "$=!$:%%~r=!" &(%echon_%!$!)