[Solved] #WM_CLOSE fails on admin windows

Just starting out? Need help? Post your questions and find answers here.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

[Solved] #WM_CLOSE fails on admin windows

Post 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! :shock:

So what can I do to close the Notepad window in future? Thanks!
Last edited by PB on Sun Dec 15, 2013 8:04 am, edited 1 time in total.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
freak
PureBasic Team
PureBasic Team
Posts: 5946
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: #WM_CLOSE fails on admin windows

Post 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.
quidquid Latine dictum sit altum videtur
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: #WM_CLOSE fails on admin windows

Post 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.
Last edited by Shield on Sun Dec 15, 2013 5:04 am, edited 1 time in total.
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: #WM_CLOSE fails on admin windows

Post by IdeasVacuum »

Isn't your app starting-up Notepad with RunProgram()? If not, then do that and you have control of what happens next.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: #WM_CLOSE fails on admin windows

Post 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.
Last edited by PB on Sun Dec 15, 2013 8:06 am, edited 1 time in total.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: #WM_CLOSE fails on admin windows

Post 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?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
JHPJHP
Addict
Addict
Posts: 2259
Joined: Sat Oct 09, 2010 3:47 am

Re: #WM_CLOSE fails on admin windows

Post by JHPJHP »

Removed; post ignored.
Last edited by JHPJHP on Sat May 26, 2018 9:09 pm, edited 2 times in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: #WM_CLOSE fails on admin windows

Post 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)
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
User avatar
skywalk
Addict
Addict
Posts: 4233
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: #WM_CLOSE fails on admin windows

Post 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)))
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: #WM_CLOSE fails on admin windows

Post by PB »

Code: Select all

PostMessage_(hWnd, #WM_SYSCOMMAND, #SC_CLOSE, 0)
Ah, that does the trick! Thanks, Shield! :)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Post Reply