Page 1 of 1
[Solved] #WM_CLOSE fails on admin windows
Posted: Sat Dec 14, 2013 4:44 pm
by PB
For years I've been using "PostMessage_(hWnd,#WM_CLOSE,0,0)" to
close a third-party window, and it's always worked because I used to
be logged in as an admin all the time.
These days I always run as a limited account, and I noticed that if I run
Notepad as an admin (right-click it and select "Run as administrator"),
that my PostMessage above doesn't actually close it anymore!
So what can I do to close the Notepad window in future? Thanks!
Re: #WM_CLOSE fails on admin windows
Posted: Sat Dec 14, 2013 5:14 pm
by freak
I don't think there is a way. If there was a way around it then the whole concept of privilege isolation would be useless.
If your target program runs as administrator then your sender program must do so as well.
Re: #WM_CLOSE fails on admin windows
Posted: Sat Dec 14, 2013 5:19 pm
by Shield
There is no solution (thanks thor!)*. If you check GetLastError(), it will return the "access denied" error code.
The only way your program can do that is if it is being run with elevated privileges as well.
Alternatively, ChangeWindowMessageFilterEx() can be used to change this behavior for a specific window.
Of course this function is probably of limited use for you as it requires admin rights as well if applied on external windows.
*edit: Apparently there is a safe one, see below.
Re: #WM_CLOSE fails on admin windows
Posted: Sat Dec 14, 2013 5:40 pm
by IdeasVacuum
Isn't your app starting-up Notepad with RunProgram()? If not, then do that and you have control of what happens next.
Re: #WM_CLOSE fails on admin windows
Posted: Sun Dec 15, 2013 2:13 am
by PB
> Isn't your app starting-up Notepad with RunProgram()?
No, see my first post.
The reason I ask how it's done, is because there's another app
which can do it, even if Notepad was launched as admin, and
even when I run that other app as limited.
Re: #WM_CLOSE fails on admin windows
Posted: Sun Dec 15, 2013 3:15 am
by IdeasVacuum
...I think it needs to be a trusted app from a known publisher. If that criteria is true, Windows will allow a temporary promotion of the User to Admin. Not sure if that remains true for Win8.1 however.
You do not explain why you want to close the other application. If I were using your app, why would I want it to close another app I have running? Does it do that without asking me first?
Re: #WM_CLOSE fails on admin windows
Posted: Sun Dec 15, 2013 4:07 am
by JHPJHP
Removed; post ignored.
Re: #WM_CLOSE fails on admin windows
Posted: Sun Dec 15, 2013 4:46 am
by Shield
I found a solution: By using WM_SYSCOMMAND you can safely send the close message
to an administrator window. WM_SYSCOMMAND will be used when default window actions
are being issued, such as closing and minimizing (via context menu) and are therefore not blocked.
Code: Select all
hwnd = FindWindow_(0, "Untitled - Notepad")
PostMessage_(hwnd, #WM_SYSCOMMAND, #SC_CLOSE, 0)
Re: #WM_CLOSE fails on admin windows
Posted: Sun Dec 15, 2013 5:12 am
by skywalk
Shield, I can't remember when or why, but I had to do the same thing for my window closer tool
Code: Select all
Structure winINFO
hW.i ; handle
left.i
top.i
right.i
bottom.i
Wd.i
Ht.i
wT$ ; window title
EndStructure
Global NewList wil.winINFO() ; Window Info list
Macro PB_CP
ProgramFilename() + "::" + #PB_Compiler_Procedure
EndMacro
Macro MRI(txt) ; MessageBox i Info = #MB_ICONASTERISK | #MB_ICONINFORMATION
MessageRequester(PB_CP, txt, #MB_ICONINFORMATION)
EndMacro
Macro MRE(txt) ; MessageBox x Error = #MB_ICONHAND | #MB_ICONSTOP | #MB_ICONERROR
MessageRequester(PB_CP, txt, #MB_ICONERROR)
EndMacro
Procedure RestoreX(DataLabel.i)
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
!MOV eax, [p.v_DataLabel] ; instead of -> !MOV eax, [esp+8]
!MOV [PB_DataPointer], eax
CompilerCase #PB_Processor_x64
!MOV rax, [p.v_DataLabel] ; instead of -> !MOV rax, [rsp+64]
!MOV [PB_DataPointer], rax
CompilerDefault
MRE("Error: Unknown Processor.")
CompilerEndSelect
EndProcedure
Procedure.i win_GetInfo_CB(hW.i, lp.i)
Protected.s wt$ = Space(#MAX_PATH)
Protected wp.WINDOWPLACEMENT
If hW
AddElement(wil())
wil()\hW = hW
If IsWindowVisible_(hW)
GetWindowText_(hW, @wt$, #MAX_PATH)
If wt$
wil()\wT$ = wt$
Debug wt$
GetWindowPlacement_(hW, @wp)
wil()\left = wp\rcNormalPosition\left
wil()\top = wp\rcNormalPosition\top
wil()\right = wp\rcNormalPosition\right
wil()\bottom = wp\rcNormalPosition\bottom
wil()\Wd = wil()\right - wil()\left
wil()\Ht = wil()\bottom - wil()\top
EndIf
EndIf
ProcedureReturn 1 ; Continue search
Else
ProcedureReturn 0 ; Done
EndIf
EndProcedure
Procedure.i CT_CloseExtraPBWin(DataLabel.i)
; Create list of existing windows + handles.
; Then cycle through and close them.
; Attempts to close via callback fails for some windows.
; CRITICAL: Delay() cmd after SendMessage_() for settling time.
Protected.i ri
Protected.s winToClose$
ClearList(wil())
EnumWindows_(@win_GetInfo_CB(), 0)
; Cycle through retrieved window list and close PB window types.
ResetList(wil())
ForEach wil()
RestoreX(DataLabel)
Repeat ; Enumerate all PB Window types
Read.s winToClose$
If FindString(wil()\wT$, winToClose$)
;ri = SendMessage_(wil()\hW, #WM_CLOSE, 0, 0) ; This fails in some cases
ri = SendMessage_(wil()\hW, #WM_SYSCOMMAND, #SC_CLOSE, 0)
Delay(50)
If ri = #S_OK
ri = 1
Else
MRE("Error: Unable to close " + wil()\wT$)
ri = -1
EndIf
Break
EndIf
Until winToClose$ = "Q"
Next
ClearList(wil())
ProcedureReturn ri
EndProcedure
DataSection
PBWindowNames:
Data.s "Asm Debugger", "Data Breakpoints", "Debug Output", "Library Viewer", "Memory Viewer"
Data.s "Procedure Callstack", "Profiler Settings", "Profiler", "Purifier Settings", "Structure Viewer"
Data.s "Variable Viewer", "Watch List", "HTML Help", "Find in files", "Platform SDK Collection"
Data.s "Q" ; Quit
EndDataSection
mri(Str(CT_CloseExtraPBWin(?PBWindowNames)))
Re: #WM_CLOSE fails on admin windows
Posted: Sun Dec 15, 2013 8:04 am
by PB
Code: Select all
PostMessage_(hWnd, #WM_SYSCOMMAND, #SC_CLOSE, 0)
Ah, that does the trick! Thanks, Shield!
