external process: get working directory (current directory)

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

external process: get working directory (current directory)

18 Oct 2017, 14:02

Can somebody help me get this to work? I.e. if possible so that x64/x32 AHK can get the working directory from x64/x32 external processes. Thanks.

I tried it with AHK x32, on Notepad x64/x32, but it didn't work.

[SOLVED]get other process's working dir - Page 2 - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/8530 ... ntry544320

I used this MCode function:

Machine code functions: Bit Wizardry - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/1948 ... dry/page-1

There is an alternative MCode function here. I'm not sure if there is a newer version.

MCode function + onlinegenerator (x86 and x64) - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/8928 ... 6-and-x64/
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
teadrinker
Posts: 1051
Joined: 29 Mar 2015, 09:41
Contact:

Re: external process: get working directory (current directory)

18 Oct 2017, 19:15

Sometime I wrote the function to get process' comandline. It reads CommandLine from RTL_USER_PROCESS_PARAMETERS structure. Also RUPP contains process' current directory.

Code: Select all

IsAdminChecking(), SetDebugPrivilege()  ; only for system processes on Windows 10 (and on Windows 8, maybe), else may by commented out

Process, Exist, winlogon.exe
PID := ErrorLevel
MsgBox, % GetProcessCurrentDirectory(PID)

GetProcessCurrentDirectory(PID)  {
   static PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, STATUS_SUCCESS := 0
   
   hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
   (A_Is64bitOS && DllCall("IsWow64Process", Ptr, hProc, UIntP, IsWow64))
   if (!A_Is64bitOS || IsWow64)
      PtrSize := 4, PtrType := "UInt", pPtr := "UIntP"
   else
      PtrSize := 8, PtrType := "Int64", pPtr := "Int64P"
   offsetCURDIR := 4*4 + PtrSize*5
   
   hModule := DllCall("GetModuleHandle", "str", "Ntdll", Ptr)
   if (A_PtrSize < PtrSize)  {            ; <<—— script 32, target process 64
      if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64QueryInformationProcess64", Ptr)
         failed := "NtWow64QueryInformationProcess64"
      if !ReadProcessMemory := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64ReadVirtualMemory64", Ptr)
         failed := "NtWow64ReadVirtualMemory64"
      info := 0, szPBI := 48, offsetPEB := 8
   }
   else  {
      if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtQueryInformationProcess", Ptr)
         failed := "NtQueryInformationProcess"
      ReadProcessMemory := "ReadProcessMemory"
      if (A_PtrSize > PtrSize)            ; <<—— script 64, target process 32
         info := 26, szPBI := 8, offsetPEB := 0
      else                                ; <<—— script and target process have the same bitness
         info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize
   }
   if failed  {
      DllCall("CloseHandle", Ptr, hProc)
      MsgBox, Failed to get pointer to %failed%
      Return
   }
   VarSetCapacity(PBI, 48, 0)
   if DllCall(QueryInformationProcess, Ptr, hProc, UInt, info, Ptr, &PBI, UInt, szPBI, UIntP, bytes) != STATUS_SUCCESS  {
      DllCall("CloseHandle", Ptr, hProc)
      Return
   }
   pPEB := NumGet(&PBI + offsetPEB, PtrType)
   DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pPEB + PtrSize * 4, pPtr, pRUPP, PtrType, PtrSize, UIntP, bytes)
   DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCURDIR, UShortP, szBuff, PtrType, 2, UIntP, bytes)
   DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCURDIR + PtrSize, pPtr, pCURDIR, PtrType, PtrSize, UIntP, bytes)
   
   VarSetCapacity(buff, szBuff, 0)
   DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pCURDIR, Ptr, &buff, PtrType, szBuff, UIntP, bytes)
   DllCall("CloseHandle", Ptr, hProc)
   Return currentDirPath := StrGet(&buff, "UTF-16")
}

IsAdminChecking()  {
   if !( A_IsAdmin || RegExMatch( DllCall("GetCommandLine", "str"), " /restart(?!\S)" ) )  {
      try  {
         if A_IsCompiled
            Run *RunAs "%A_ScriptFullPath%" /restart
         else
            Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
      }
      ExitApp
   }
}

SetDebugPrivilege()  {
   static PROCESS_QUERY_INFORMATION := 0x400, TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2
   
   hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION, Int, false, UInt, DllCall("GetCurrentProcessId"), Ptr)
   DllCall("Advapi32\OpenProcessToken", Ptr, hProc, UInt, TOKEN_ADJUST_PRIVILEGES, PtrP, token)
   
   DllCall("Advapi32\LookupPrivilegeValue", Ptr, 0, Str, "SeDebugPrivilege", Int64P, luid)
   VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
   NumPut(1, TOKEN_PRIVILEGES, "UInt")
   NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
   NumPut(SE_PRIVILEGE_ENABLED, TOKEN_PRIVILEGES, 12, "UInt")
   DllCall("Advapi32\AdjustTokenPrivileges", Ptr, token, Int, false, Ptr, &TOKEN_PRIVILEGES, UInt, 0, Ptr, 0, Ptr, 0)
   res := A_LastError
   DllCall("CloseHandle", Ptr, token)
   DllCall("CloseHandle", Ptr, hProc)
   Return res  ; success 0
}
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: external process: get working directory (current directory)

18 Oct 2017, 19:47

This is really great, many thanks, and it doesn't need a machine code function.

You've been posting a lot of good stuff the last few months.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: external process: get working directory (current directory)

18 Oct 2017, 20:14

Haha you're here to practise your English, classic.

Hmm, the comment about system processes, reminded me, I wanted a way to get the user name for a process. I've started a new thread here:

process: get user name (like Task Manager) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=38546
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask For Help”

Who is online

Users browsing this forum: Albireo, Google [Bot], Odlanir, pn4265 and 248 guests