Message258945
> An .lnk is launched with ShellExecute which returns control
> immediately upon successful launch
cmd calls ShellExecuteEx, not ShellExecute, and it uses the flags SEE_MASK_NO_CONSOLE (0x8000, don't create a new console) and SEE_MASK_NOCLOSEPROCESS (0x0040, return a process handle if possible).
Here's a walk-through with a debugger attached to cmd while executing a LNK shortcut to "C:\Program Files\Python27\python.exe":
C:\Temp>.\python.lnk -c "import sys,time;time.sleep(60);sys.exit(42)"
Breakpoint 0 hit
SHELL32!ShellExecuteExW:
00007ff9`a5710e20 48895c2408 mov qword ptr [rsp+8],rbx
ss:000000a3`eb3af3a0=000000a3eb597ca0
0:000> ; as /x info @rcx
0:000> ; as /x sz @@(*((unsigned long *)${info}))
0:000> bd 2,3,4; pt; be 2,3,4
ShellExecuteEx returns the process handle:
0:000> ?? *((void **)(${info} + ${sz} - 8)); * hProcess
void * 0x00000000`000002fc
0:000> !handle 2fc
Handle 2fc
Type Process
0:000> g
cmd uses the handle to read the ImageSubsystem type from the process environment block (PEB), for which 3 is a console process and 2 is a GUI process.
Breakpoint 1 hit
cmd!GetProcessSubsystemType:
00007ff7`a133faf4 48895c2410 mov qword ptr [rsp+10h],rbx
ss:000000a3`eb3af458=000000a3eb585640
0:000> g
Breakpoint 2 hit
KERNELBASE!ReadProcessMemory:
00007ff9`a49ac230 4883ec48 sub rsp,48h
0:000> as /x buf @r8
0:000> pt
KERNELBASE!ReadProcessMemory+0x2b:
00007ff9`a49ac25b c3 ret
0:000> ?? ((ntdll!_PEB *)${buf})->ImageSubsystem
unsigned long 3
0:000> g
Since it's a console process, cmd waits and queries the exit code.
Breakpoint 3 hit
KERNELBASE!WaitForSingleObject:
00007ff9`a49840c0 4533c0 xor r8d,r8d
0:000> r rcx
rcx=00000000000002fc
0:000> g
Breakpoint 4 hit
KERNELBASE!GetExitCodeProcess:
00007ff9`a49c46d0 4053 push rbx
0:000> as /x rc @rdx
0:000> pt
KERNELBASE!GetExitCodeProcess+0x3a:
00007ff9`a49c470a c3 ret
0:000> ?? *((unsigned long *)${rc})
unsigned long 0x2a
0:000> ? 0x2a
Evaluate expression: 42 = 00000000`0000002a
It sets the exit code in the 'hidden' environment variable "=ExitCode" as a unsigned hexadecimal number.
C:\Temp>echo %=ExitCode%
0000002A
You can also query the signed value using the pseudo environment variable "errorlevel".
C:\Temp>echo %errorlevel%
42 |
|
Date |
User |
Action |
Args |
2016-01-26 04:23:21 | eryksun | set | recipients:
+ eryksun, paul.moore, tim.golden, zach.ware, steve.dower, Ivan.Pozdeev |
2016-01-26 04:23:21 | eryksun | set | messageid: <1453782201.5.0.210485589702.issue26189@psf.upfronthosting.co.za> |
2016-01-26 04:23:21 | eryksun | link | issue26189 messages |
2016-01-26 04:23:20 | eryksun | create | |
|