{-# LINE 1 "System\\Win32\\Process.hsc" #-}



{-# LINE 2 "System\\Win32\\Process.hsc" #-}

{-# LANGUAGE Safe #-}



{-# LINE 6 "System\\Win32\\Process.hsc" #-}

-----------------------------------------------------------------------------

-- |

-- Module      :  System.Win32.Process

-- Copyright   :  (c) Alastair Reid, 1997-2003

-- License     :  BSD-style (see the file libraries/base/LICENSE)

--

-- Maintainer  :  Esa Ilari Vuokko <ei@vuokko.info>

-- Stability   :  provisional

-- Portability :  portable

--

-- A collection of FFI declarations for interfacing with Win32.

--

-----------------------------------------------------------------------------



module System.Win32.Process where

import Control.Exception    ( bracket )

import Control.Monad        ( liftM5 )

import Foreign              ( Ptr, peekByteOff, allocaBytes, pokeByteOff

                            , plusPtr )

import Foreign.C.Types      ( CUInt(..) )

import System.Win32.File    ( closeHandle )

import System.Win32.Types



#include "windows_cconv.h"









-- constant to wait for a very long time.

iNFINITE :: DWORD

iNFINITE = 4294967295

{-# LINE 37 "System\\Win32\\Process.hsc" #-}



foreign import WINDOWS_CCONV unsafe "windows.h Sleep"

  sleep :: DWORD -> IO ()





type ProcessId = DWORD

type ProcessHandle = HANDLE

type ProcessAccessRights = DWORD

pROCESS_ALL_ACCESS             :: ProcessAccessRights

pROCESS_ALL_ACCESS             =  2035711

pROCESS_CREATE_PROCESS         :: ProcessAccessRights

pROCESS_CREATE_PROCESS         =  128

pROCESS_CREATE_THREAD          :: ProcessAccessRights

pROCESS_CREATE_THREAD          =  2

pROCESS_DUP_HANDLE             :: ProcessAccessRights

pROCESS_DUP_HANDLE             =  64

pROCESS_QUERY_INFORMATION      :: ProcessAccessRights

pROCESS_QUERY_INFORMATION      =  1024

pROCESS_SET_QUOTA              :: ProcessAccessRights

pROCESS_SET_QUOTA              =  256

pROCESS_SET_INFORMATION        :: ProcessAccessRights

pROCESS_SET_INFORMATION        =  512

pROCESS_TERMINATE              :: ProcessAccessRights

pROCESS_TERMINATE              =  1

pROCESS_VM_OPERATION           :: ProcessAccessRights

pROCESS_VM_OPERATION           =  8

pROCESS_VM_READ                :: ProcessAccessRights

pROCESS_VM_READ                =  16

pROCESS_VM_WRITE               :: ProcessAccessRights

pROCESS_VM_WRITE               =  32



{-# LINE 58 "System\\Win32\\Process.hsc" #-}



foreign import WINDOWS_CCONV unsafe "windows.h OpenProcess"

    c_OpenProcess :: ProcessAccessRights -> BOOL -> ProcessId -> IO ProcessHandle





openProcess :: ProcessAccessRights -> BOOL -> ProcessId -> IO ProcessHandle

openProcess r inh i = failIfNull "OpenProcess" $ c_OpenProcess r inh i



foreign import WINDOWS_CCONV unsafe "windows.h GetProcessId"

    c_GetProcessId :: ProcessHandle -> IO ProcessId



getProcessId :: ProcessHandle -> IO ProcessId

getProcessId h = failIfZero "GetProcessId" $ c_GetProcessId h



foreign import WINDOWS_CCONV unsafe "windows.h GetCurrentProcess"

    c_GetCurrentProcess :: IO ProcessHandle



foreign import WINDOWS_CCONV unsafe "windows.h GetCurrentProcessId"

    c_GetCurrentProcessId :: IO ProcessId



getCurrentProcessId :: IO ProcessId

getCurrentProcessId = c_GetCurrentProcessId



getCurrentProcess :: IO ProcessHandle

getCurrentProcess = c_GetCurrentProcess



foreign import WINDOWS_CCONV unsafe "windows.h TerminateProcess"

    c_TerminateProcess :: ProcessHandle -> CUInt -> IO Bool



terminateProcessById :: ProcessId -> IO ()

terminateProcessById p = bracket

    (openProcess pROCESS_TERMINATE False p)

    closeHandle

    (\h -> failIfFalse_ "TerminateProcess" $ c_TerminateProcess h 1)



type Th32SnapHandle = HANDLE

type Th32SnapFlags = DWORD

-- | ProcessId, number of threads, parent ProcessId, process base priority, path of executable file

type ProcessEntry32 = (ProcessId, Int, ProcessId, LONG, String)



tH32CS_SNAPALL         :: Th32SnapFlags

tH32CS_SNAPALL         =  15

tH32CS_SNAPHEAPLIST    :: Th32SnapFlags

tH32CS_SNAPHEAPLIST    =  1

tH32CS_SNAPMODULE      :: Th32SnapFlags

tH32CS_SNAPMODULE      =  8

tH32CS_SNAPPROCESS     :: Th32SnapFlags

tH32CS_SNAPPROCESS     =  2

tH32CS_SNAPTHREAD      :: Th32SnapFlags

tH32CS_SNAPTHREAD      =  4



{-# LINE 105 "System\\Win32\\Process.hsc" #-}

{-

    , tH32CS_SNAPGETALLMODS = TH32CS_GETALLMODS

    , tH32CS_SNAPNOHEAPS    = TH32CS_SNAPNOHEAPS

-}



foreign import WINDOWS_CCONV unsafe "tlhelp32.h CreateToolhelp32Snapshot"

    c_CreateToolhelp32Snapshot :: Th32SnapFlags -> ProcessId -> IO Th32SnapHandle



foreign import WINDOWS_CCONV unsafe "tlhelp32.h Process32FirstW"

    c_Process32First :: Th32SnapHandle -> Ptr ProcessEntry32 -> IO BOOL



foreign import WINDOWS_CCONV unsafe "tlhelp32.h Process32NextW"

    c_Process32Next :: Th32SnapHandle -> Ptr ProcessEntry32 -> IO BOOL



-- | Create a snapshot of specified resources.  Call closeHandle to close snapshot.

createToolhelp32Snapshot :: Th32SnapFlags -> Maybe ProcessId -> IO Th32SnapHandle

createToolhelp32Snapshot f p

    = failIfNull "CreateToolhelp32Snapshot" $ c_CreateToolhelp32Snapshot

        f (maybe 0 id p)



withTh32Snap :: Th32SnapFlags -> Maybe ProcessId -> (Th32SnapHandle -> IO a) -> IO a

withTh32Snap f p = bracket (createToolhelp32Snapshot f p) (closeHandle)





peekProcessEntry32 :: Ptr ProcessEntry32 -> IO ProcessEntry32

peekProcessEntry32 buf = liftM5 (,,,,)

    (((\hsc_ptr -> peekByteOff hsc_ptr 8)) buf)

{-# LINE 132 "System\\Win32\\Process.hsc" #-}

    (((\hsc_ptr -> peekByteOff hsc_ptr 28)) buf)

{-# LINE 133 "System\\Win32\\Process.hsc" #-}

    (((\hsc_ptr -> peekByteOff hsc_ptr 32)) buf)

{-# LINE 134 "System\\Win32\\Process.hsc" #-}

    (((\hsc_ptr -> peekByteOff hsc_ptr 36)) buf)

{-# LINE 135 "System\\Win32\\Process.hsc" #-}

    (peekTString $ ((\hsc_ptr -> hsc_ptr `plusPtr` 44)) buf)

{-# LINE 136 "System\\Win32\\Process.hsc" #-}



-- | Enumerate processes using Process32First and Process32Next

th32SnapEnumProcesses :: Th32SnapHandle -> IO [ProcessEntry32]

th32SnapEnumProcesses h = allocaBytes ((568)) $ \pe -> do

{-# LINE 140 "System\\Win32\\Process.hsc" #-}

    ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) pe (((568))::DWORD)

{-# LINE 141 "System\\Win32\\Process.hsc" #-}

    ok <- c_Process32First h pe

    readAndNext ok pe []

    where

        readAndNext ok pe res

            | not ok    = do

                err <- getLastError

                if err == (18)

{-# LINE 148 "System\\Win32\\Process.hsc" #-}

                    then return $ reverse res

                    else failWith "th32SnapEnumProcesses: Process32First/Process32Next" err

            | otherwise = do

                entry <- peekProcessEntry32 pe

                ok' <- c_Process32Next h pe

                readAndNext ok' pe (entry:res)