Jump to content
Sign in to follow this  
cjconstantine

Detect what file a process has open

Recommended Posts

cjconstantine

Ok, after much searching the answer has eluded me. I know how to tell when a process has started, but what I want to know is if that process has a file opened. (IE a user start Excel to view an .xls file ... is it possible to know what .xls file was opened?)

Any ideas where to start?

*EDIT*

I'd rather keep within the confines of AutoIt ...

Edited by cjconstantine

Share this post


Link to post
Share on other sites
Fire

May be: ?

if ProcessExists("notepad.exe") Then 
    msgbox(64, "aaa", "Proses var")
Else
    MsgBox(64, "Proses Yoxdur!", "No Process notepad.exe")
    EndIf

[size="5"] [/size]

Share this post


Link to post
Share on other sites
cjconstantine

All that would do is let me know that Notepad.exe is running, what I need to know is what file Notepad.exe has open.

Share this post


Link to post
Share on other sites
Fire

Try this: may be it help:

$a ="excel.exe" 
$b =WinGetTitle(" ", " ")
if ProcessExists($a) Then
    msgbox(64, "aaa", "Proses var")
    MsgBox(64, "title", WinGetTitle("[active]") & @CRLF)
     
    
    


Else
    MsgBox(64, "Proses Yoxdur!", "No Process  excel.exe")
EndIf
Edited by Sh3llC043r

[size="5"] [/size]

Share this post


Link to post
Share on other sites
PsaltyDS

Try this: may be it help:

No, it doesn't. Don't reply if you're not going to try to understand the question first.

@cjconstantine: Utilities that perform this operation first install a driver that intercepts the information from the Windows kernel. The information is not normally available from Windows without that modification, and I don't think AutoIt is the right language to try and get it.

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites
cjconstantine

@PsaltyDS: That's what I was afraid of ... ok, I'll have to stick with using Sysinternals' Handle.exe app and parsing the output. Not as elegant as I hoped but it works.

Thanks!

Share this post


Link to post
Share on other sites
weaponx

Try this: may be it help:

$a ="excel.exe" 
$b =WinGetTitle(" ", " ")
if ProcessExists($a) Then
    msgbox(64, "aaa", "Proses var")
    MsgBox(64, "title", WinGetTitle("[active]") & @CRLF)
 
    
    


Else
    MsgBox(64, "Proses Yoxdur!", "No Process excel.exe")
EndIf

Wow. What a terrible response to an obvious question.

Share this post


Link to post
Share on other sites
Authenticity

You got a lot of things to read, if you got the time and the motivation. I don't have the WDK that contains all the definitions over here but a few resources I could find:

Querying system handles:

Example 1, and http://fy.chalmers.se/~appro/LD_*-gallery/WINLOGOUT.c

Ntdll.dll functions prototypes:

Ntdll.dll

The rest of the things you need to do is to duplicate the handle using DuplicateHandle, use ZwQueryObject to get the handle type as a string, and then ZwQueryInformationFile to get the file name. A lot of work just for so little and it's very slow :)

#Include <WinAPI.au3>
SetPrivilege("SeDebugPrivilege", True)

Global Const $DUPLICATE_SAME_ATTRIBUTES = 0x00000004
Global Const $PROCESS_DUP_HANDLE = 0x00000040
Global Const $SystemHandleInformation = 16
Global Const $STATUS_INFO_LENGTH_MISMATCH = 3221225476

; "uint ProcessId;ubyte ObjectTypeNumber;ubyte Flags;ushort Handle;ptr Object;uint GrantedAccess;"
Global Const $tagSYSTEM_HANDLE_INFORMATION = "uint;ubyte;ubyte;ushort;ptr;uint;"
; "uint NumberOfHandles;" & $tagSYSTEM_HANDLE_INFORMATION
Global Const $tagSYSTEM_HANDLE_INFORMATIONEX = "uint;" & $tagSYSTEM_HANDLE_INFORMATION
Global Const $tagUNICODE_STRING = "ushort Length;ushort MaximumLength;ptr Buffer;"
Global Const $tagPUBLIC_OBJECT_TYPE_INFORMATION = $tagUNICODE_STRING & "uint Reserved[22];"

Local $ScitePID = ProcessExists("scite.exe")
Local $hProc = _WinAPI_OpenProcess($PROCESS_DUP_HANDLE, False, $ScitePID)
Local $tHandlesInfo, $pHandlesInfo
Local $iRes

$tHandlesInfo = DllStructCreate($tagSYSTEM_HANDLE_INFORMATIONEX)
$pHandlesInfo = DllStructGetPtr($tHandlesInfo)
$iRes = _WinAPI_ZwQuerySystemInformation($SystemHandleInformation, $pHandlesInfo, DllStructGetSize($tHandlesInfo))

If $iRes = $STATUS_INFO_LENGTH_MISMATCH Then
    Local $sString = "uint;"
    Local $iSize = @extended

    For $i = 1 To ($iSize-4)/16
        $sString &= $tagSYSTEM_HANDLE_INFORMATION
    Next

    $tHandlesInfo = DllStructCreate($sString)
    $pHandlesInfo = DllStructGetPtr($tHandlesInfo)
    $iRes = _WinAPI_ZwQuerySystemInformation($SystemHandleInformation, $pHandlesInfo, $iSize)
    Local $tPOTI, $pPOTI, $iPOTI
    
    $tPOTI = DllStructCreate($tagPUBLIC_OBJECT_TYPE_INFORMATION)
    $pPOTI = DllStructGetPtr($tPOTI)
    $iPOTI = DllStructGetSize($tPOTI)
    
    If $iRes = 0 Then
        For $i = 0 To DllStructGetData($tHandlesInfo, 1)-1
            If DllStructGetData($tHandlesInfo, $i*6+2) = $ScitePID Then 
                ; Now duplicate the handle, it's DllStructGetData($tHandlesInfo, $i*6+5).
                ; Get the handle type as a string: _WinAPI_ZwQueryObject.
                ; Finally, use ZwQueryInformationFile with the duplicated handle to retrieve file name.
            EndIf
        Next
    EndIf
EndIf
_WinAPI_CloseHandle($hProc)


;==================================================================================
; Function:         SetPrivilege( $privilege, $bEnable )
; Description:      Enables (or disables) the $privilege on the current process
;                   (Probably) requires administrator privileges to run
;
; Author(s):        Larry (from autoitscript.com's Forum)
; Notes(s):
; http://www.autoitscript.com/forum/index.php?s=&showtopic=31248&view=findpost&p=223999
;==================================================================================

Func SetPrivilege( $privilege, $bEnable )
    Const $MY_TOKEN_ADJUST_PRIVILEGES = 0x0020
    Const $MY_TOKEN_QUERY = 0x0008
    Const $MY_SE_PRIVILEGE_ENABLED = 0x0002
    Local $hToken, $SP_auxret, $SP_ret, $hCurrProcess, $nTokens, $nTokenIndex, $priv
    $nTokens = 1
    $LUID = DLLStructCreate("dword;int")
    If IsArray($privilege) Then    $nTokens = UBound($privilege)
    $TOKEN_PRIVILEGES = DLLStructCreate("dword;dword[" & (3 * $nTokens) & "]")
    $NEWTOKEN_PRIVILEGES = DLLStructCreate("dword;dword[" & (3 * $nTokens) & "]")
    $hCurrProcess = DLLCall("kernel32.dll","hwnd","GetCurrentProcess")
    $SP_auxret = DLLCall("advapi32.dll","int","OpenProcessToken","hwnd",$hCurrProcess[0],   _
            "int",BitOR($MY_TOKEN_ADJUST_PRIVILEGES,$MY_TOKEN_QUERY),"int*",0)
    If $SP_auxret[0] Then
        $hToken = $SP_auxret[3]
        DLLStructSetData($TOKEN_PRIVILEGES,1,1)
        $nTokenIndex = 1
        While $nTokenIndex <= $nTokens
            If IsArray($privilege) Then
                $priv = $privilege[$nTokenIndex-1]
            Else
                $priv = $privilege
            EndIf
            $ret = DLLCall("advapi32.dll","int","LookupPrivilegeValue","str","","str",$priv,   _
                    "ptr",DLLStructGetPtr($LUID))
            If $ret[0] Then
                If $bEnable Then
                    DLLStructSetData($TOKEN_PRIVILEGES,2,$MY_SE_PRIVILEGE_ENABLED,(3 * $nTokenIndex))
                Else
                    DLLStructSetData($TOKEN_PRIVILEGES,2,0,(3 * $nTokenIndex))
                EndIf
                DLLStructSetData($TOKEN_PRIVILEGES,2,DllStructGetData($LUID,1),(3 * ($nTokenIndex-1)) + 1)
                DLLStructSetData($TOKEN_PRIVILEGES,2,DllStructGetData($LUID,2),(3 * ($nTokenIndex-1)) + 2)
                DLLStructSetData($LUID,1,0)
                DLLStructSetData($LUID,2,0)
            EndIf
            $nTokenIndex += 1
        WEnd
        $ret = DLLCall("advapi32.dll","int","AdjustTokenPrivileges","hwnd",$hToken,"int",0,   _
                "ptr",DllStructGetPtr($TOKEN_PRIVILEGES),"int",DllStructGetSize($NEWTOKEN_PRIVILEGES),   _
                "ptr",DllStructGetPtr($NEWTOKEN_PRIVILEGES),"int*",0)
        $f = DLLCall("kernel32.dll","int","GetLastError")
    EndIf
    $NEWTOKEN_PRIVILEGES=0
    $TOKEN_PRIVILEGES=0
    $LUID=0
    If $SP_auxret[0] = 0 Then Return 0
    $SP_auxret = DLLCall("kernel32.dll","int","CloseHandle","hwnd",$hToken)
    If Not $ret[0] And Not $SP_auxret[0] Then Return 0
    return $ret[0]
EndFunc   ;==>SetPrivilege

Func _WinAPI_ZwQuerySystemInformation($iSystemInformationClass, $pSystemInformation, $iSystemInformationLength)
    Local $aResult = DllCall("ntdll.dll", "uint", "ZwQuerySystemInformation", _
                                          "int", $iSystemInformationClass, _
                                          "ptr", $pSystemInformation, _
                                          "uint", $iSystemInformationLength, _
                                          "uint*", 0)
                                          
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, $aResult[4], $aResult[0])
EndFunc

Func _WinAPI_ZwQueryObject($hObject, $iObjectInformationClass, $pObjectInformation, $iObjectInformationLength)
    Local $aResult = DllCall("ntdll.dll", "uint", "ZwQueryObject", _
                                          "hwnd", $hObject, _
                                          "int", $iObjectInformationClass, _
                                          "ptr", $pObjectInformation, _
                                          "uint", $iObjectInformationLength, _
                                          "uint*", 0)
                        
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, $aResult[5], $aResult[0])
EndFunc

Edit: ..and NTSTATUS codes

Edited by Authenticity

Share this post


Link to post
Share on other sites
cjconstantine

That a whole lotta code to go thru. My ultimate goal was to detect if an Office app had opened a file with an embedded flash object and if so, kill the process. Here's what I came up with:

#include <Constants.au3>
#include <Array.au3>

_EmbeddedGameScan('excel.exe')

Func _EmbeddedGameScan($OfficeApp)
    If Not ProcessExists($OfficeApp) Then Return

    $pid = Run('Handle -p ' & $OfficeApp, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

    $read = ''
    While 1
        $read &= StdoutRead($pid)
        If @error Then ExitLoop
    WEnd

    $read = StringSplit($read, @CRLF, 1)
    If $read[0] < 7 Then Return

    $pid = StringTrimLeft($read[7], StringInStr($read[7], 'pid: ') + 4)
    $length = 1

    While 1
        If StringMid($pid, $length, 1) = ' ' Then ExitLoop
        $length += 1
    WEnd

    $pid = StringLeft($pid, $length - 1)

    If _ArraySearch($read, 'File  (R--)   ' & @SystemDir & '\Macromed\Flash\', 1, 0, 0, 1) > 0 Then ProcessClose($pid)
EndFunc
Edited by cjconstantine

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×