/***************************************************************************\
*									    *
*   WINPROC.H                                                               *
*									    *
*   Some headers are used from the cygnus project                           *
*   Modified by:                                                            *
*    kiefer@isys.de                                                         *
*    rainer@mathematik.uni-bielefeld.de                                     *
*									    *
\***************************************************************************/

#if !defined (_WINPROC_H)
#define _WINPROC_H

#ifdef __cplusplus
extern "C" {
#endif

#define DLL_PROCESS_ATTACH 1
#define DLL_THREAD_ATTACH  2
#define DLL_THREAD_DETACH  3
#define DLL_PROCESS_DETACH 0

#define STATUS_WAIT_0			 ((DWORD)0x00000000L)
#define STATUS_ABANDONED_WAIT_0 	 ((DWORD)0x00000080L)
#define STATUS_USER_APC 		 ((DWORD)0x000000C0L)
#define STATUS_TIMEOUT			 ((DWORD)0x00000102L)
#define STATUS_PENDING			 ((DWORD)0x00000103L)
#define STATUS_GUARD_PAGE_VIOLATION	 ((DWORD)0x80000001L)
#define STATUS_DATATYPE_MISALIGNMENT	 ((DWORD)0x80000002L)
#define STATUS_BREAKPOINT		 ((DWORD)0x80000003L)
#define STATUS_SINGLE_STEP		 ((DWORD)0x80000004L)
#define STATUS_ACCESS_VIOLATION 	 ((DWORD)0xC0000005L)
#define STATUS_IN_PAGE_ERROR		 ((DWORD)0xC0000006L)
#define STATUS_NO_MEMORY		 ((DWORD)0xC0000017L)
#define STATUS_ILLEGAL_INSTRUCTION	 ((DWORD)0xC000001DL)
#define STATUS_NONCONTINUABLE_EXCEPTION  ((DWORD)0xC0000025L)
#define STATUS_INVALID_DISPOSITION	 ((DWORD)0xC0000026L)
#define STATUS_ARRAY_BOUNDS_EXCEEDED	 ((DWORD)0xC000008CL)
#define STATUS_FLOAT_DENORMAL_OPERAND	 ((DWORD)0xC000008DL)
#define STATUS_FLOAT_DIVIDE_BY_ZERO	 ((DWORD)0xC000008EL)
#define STATUS_FLOAT_INEXACT_RESULT	 ((DWORD)0xC000008FL)
#define STATUS_FLOAT_INVALID_OPERATION	 ((DWORD)0xC0000090L)
#define STATUS_FLOAT_OVERFLOW		 ((DWORD)0xC0000091L)
#define STATUS_FLOAT_STACK_CHECK	 ((DWORD)0xC0000092L)
#define STATUS_FLOAT_UNDERFLOW		 ((DWORD)0xC0000093L)
#define STATUS_INTEGER_DIVIDE_BY_ZERO	 ((DWORD)0xC0000094L)
#define STATUS_INTEGER_OVERFLOW 	 ((DWORD)0xC0000095L)
#define STATUS_PRIVILEGED_INSTRUCTION	 ((DWORD)0xC0000096L)
#define STATUS_STACK_OVERFLOW		 ((DWORD)0xC00000FDL)
#define STATUS_CONTROL_C_EXIT		 ((DWORD)0xC000013AL)

#define WAIT_FAILED		((DWORD) 0xFFFFFFFFL)
#define WAIT_OBJECT_0		STATUS_WAIT_0
#define WAIT_ABANDONED		STATUS_ABANDONED_WAIT_0
#define WAIT_ABANDONED_0	STATUS_ABANDONED_WAIT_0
#define WAIT_TIMEOUT		STATUS_TIMEOUT
#define WAIT_IO_COMPLETION	STATUS_USER_APC
#define STILL_ACTIVE		STATUS_PENDING

typedef struct {
    DWORD	dwOemId;
    DWORD	dwPageSize;
    LPVOID	lpMinimumApplicationAddress;
    LPVOID	lpMaximumApplicationAddress;
    DWORD	dwActiveProcessorMask;
    DWORD	dwNumberOfProcessors;
    DWORD	dwProcessorType;
    DWORD	dwAllocationGranularity;
    DWORD	dwReserved;
} SYSTEM_INFO, *LPSYSTEM_INFO;

VOID WINAPI GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);

#define DEBUG_PROCESS		    0x00000001
#define DEBUG_ONLY_THIS_PROCESS     0x00000002
#define CREATE_SUSPENDED	    0x00000004
#define DETACHED_PROCESS	    0x00000008
#define CREATE_NEW_CONSOLE	    0x00000010

#define NORMAL_PRIORITY_CLASS	    0x00000020
#define IDLE_PRIORITY_CLASS	    0x00000040
#define HIGH_PRIORITY_CLASS	    0x00000080
#define REALTIME_PRIORITY_CLASS     0x00000100

#define CREATE_NEW_PROCESS_GROUP    0x00000200
#define CREATE_UNICODE_ENVIRONMENT  0x00000400

#define STARTF_USESHOWWINDOW	0x00000001
#define STARTF_USESIZE		0x00000002
#define STARTF_USEPOSITION	0x00000004
#define STARTF_USECOUNTCHARS	0x00000008
#define STARTF_USEFILLATTRIBUTE 0x00000010
#define STARTF_RUNFULLSCREEN	0x00000020
#define STARTF_FORCEONFEEDBACK	0x00000040
#define STARTF_FORCEOFFFEEDBACK 0x00000080
#define STARTF_USESTDHANDLES	0x00000100
#define STARTF_USEHOTKEY	0x00000200

typedef struct {
    DWORD	cb;
    LPTSTR   lpReserved;
    LPTSTR   lpDesktop;
    LPTSTR   lpTitle;
    DWORD	dwX;
    DWORD	dwY;
    DWORD	dwXSize;
    DWORD	dwYSize;
    DWORD	dwXCountChars;
    DWORD	dwYCountChars;
    DWORD	dwFillAttribute;
    DWORD	dwFlags;
    WORD	wShowWindow;
    WORD	cbReserved2;
    LPBYTE	lpReserved2;
    HANDLE	hStdInput;
    HANDLE	hStdOutput;
    HANDLE	hStdError;
} STARTUPINFO, *LPSTARTUPINFO;

#define GetStartupInfo TFUNCT(GetStartupInfo)
VOID WINAPI GetStartupInfo(LPSTARTUPINFO lpStartupInfo);

typedef struct {
    HANDLE	hProcess;
    HANDLE	hThread;
    DWORD	dwProcessId;
    DWORD	dwThreadId;
} PROCESS_INFORMATION, *PPROCESS_INFORMATION,
* LPPROCESS_INFORMATION;

#define CreateProcess TFUNCT(CreateProcess)
BOOL WINAPI CreateProcess(LPCTSTR lpName, LPTSTR lpCommandline,
	LPSECURITY_ATTRIBUTES lpProcessAttr,
	LPSECURITY_ATTRIBUTES lpThreadAttr,
	BOOL fInherit, DWORD dwCreation, LPVOID lpEnviron,
	LPCTSTR lpCurrentDir, LPSTARTUPINFO lpStartup, 
	LPPROCESS_INFORMATION lpProcessInfo);

BOOL WINAPI GetProcessTimes(HANDLE hProcess, LPFILETIME lpCreationTime,
	LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime);
HANDLE WINAPI OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle,
	DWORD dwProcessId);
HANDLE WINAPI GetCurrentProcess(VOID);
DWORD WINAPI GetCurrentProcessId(VOID);
VOID WINAPI ExitProcess(UINT uExitCode);
BOOL WINAPI TerminateProcess(HANDLE hProcess, UINT uExitCode);
BOOL WINAPI GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode);
VOID WINAPI FatalExit(int ExitCode);


typedef DWORD WINAPI (*PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;

HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
	DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,
	LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
DWORD WINAPI SuspendThread(HANDLE hThread);
DWORD WINAPI ResumeThread(HANDLE hThread);
VOID WINAPI ExitThread(DWORD dwExitCode);
BOOL WINAPI TerminateThread(HANDLE hThread, DWORD dwExitCode);
HANDLE WINAPI GetCurrentThread(VOID);
DWORD WINAPI GetCurrentThreadId(VOID);
BOOL WINAPI GetExitCodeThread(HANDLE hThread,LPDWORD lpExitCode);
BOOL WINAPI GetThreadTimes(HANDLE hThread,
	LPFILETIME lpCreationTime, LPFILETIME lpExitTime,
	LPFILETIME lpKernelTime, LPFILETIME lpUserTime);

#define THREAD_BASE_PRIORITY_LOWRT	15
#define THREAD_BASE_PRIORITY_MAX	2
#define THREAD_BASE_PRIORITY_MIN		(-2)
#define THREAD_BASE_PRIORITY_IDLE	(-15)

#define THREAD_PRIORITY_LOWEST	THREAD_BASE_PRIORITY_MIN
#define THREAD_PRIORITY_BELOW_NORMAL	(THREAD_PRIORITY_LOWEST+1)
#define THREAD_PRIORITY_NORMAL	0
#define THREAD_PRIORITY_HIGHEST	THREAD_BASE_PRIORITY_MAX
#define THREAD_PRIORITY_ABOVE_NORMAL	(THREAD_PRIORITY_HIGHEST-1)
#define THREAD_PRIORITY_ERROR_RETURN	(MAXLONG)
#define THREAD_PRIORITY_TIME_CRITICAL	THREAD_BASE_PRIORITY_LOWRT
#define THREAD_PRIORITY_IDLE	THREAD_BASE_PRIORITY_IDLE

BOOL WINAPI SetThreadPriority(HANDLE hThread, int nPriority);
int WINAPI GetThreadPriority(HANDLE hThread);

#define GetCommandLine TFUNCT(GetCommandLine)
LPTSTR WINAPI GetCommandLine(void);

char * RtlUnwind(void *,void *,void *,void *) WINAPI;


/* ExceptionCodes */
#define EXCEPTION_ACCESS_VIOLATION	   STATUS_ACCESS_VIOLATION
#define EXCEPTION_DATATYPE_MISALIGNMENT    STATUS_DATATYPE_MISALIGNMENT
#define EXCEPTION_BREAKPOINT	STATUS_BREAKPOINT
#define EXCEPTION_SINGLE_STEP	STATUS_SINGLE_STEP
#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED    STATUS_ARRAY_BOUNDS_EXCEEDED
#define EXCEPTION_FLT_DENORMAL_OPERAND	   STATUS_FLOAT_DENORMAL_OPERAND
#define EXCEPTION_FLT_DIVIDE_BY_ZERO	   STATUS_FLOAT_DIVIDE_BY_ZERO
#define EXCEPTION_FLT_INEXACT_RESULT	   STATUS_FLOAT_INEXACT_RESULT
#define EXCEPTION_FLT_INVALID_OPERATION    STATUS_FLOAT_INVALID_OPERATION
#define EXCEPTION_FLT_OVERFLOW	STATUS_FLOAT_OVERFLOW
#define EXCEPTION_FLT_STACK_CHECK	   STATUS_FLOAT_STACK_CHECK
#define EXCEPTION_FLT_UNDERFLOW 	   STATUS_FLOAT_UNDERFLOW
#define EXCEPTION_INT_DIVIDE_BY_ZERO	   STATUS_INTEGER_DIVIDE_BY_ZERO
#define EXCEPTION_INT_OVERFLOW	    STATUS_INTEGER_OVERFLOW
#define EXCEPTION_PRIV_INSTRUCTION  STATUS_PRIVILEGED_INSTRUCTION
#define EXCEPTION_IN_PAGE_ERROR     STATUS_IN_PAGE_ERROR
#define EXCEPTION_ILLEGAL_INSTRUCTION	   STATUS_ILLEGAL_INSTRUCTION
#define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION
#define EXCEPTION_STACK_OVERFLOW	   STATUS_STACK_OVERFLOW
#define EXCEPTION_INVALID_DISPOSITION	   STATUS_INVALID_DISPOSITION
#define EXCEPTION_GUARD_PAGE		   STATUS_GUARD_PAGE_VIOLATION
#define CONTROL_C_EXIT		     STATUS_CONTROL_C_EXIT

#define EXCEPTION_CTRL_C

#define EXCEPTION_MAXIMUM_PARAMETERS    15
#define EXCEPTION_NONCONTINUABLE        1

VOID WINAPI RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags,
	DWORD nNumberOfArguments, CONST DWORD *lpArguments);

typedef struct __erec {
    DWORD	    ExceptionCode;
    DWORD	    ExceptionFlags;
    struct __erec   *ExceptionRecord;
    void *	    ExceptionAddress;
    DWORD	    NumberParameters;
    DWORD	    ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD, *PEXCEPTION_RECORD;

/* values for dwDebugEventCode */

#define EXCEPTION_DEBUG_EVENT	    1
#define CREATE_THREAD_DEBUG_EVENT   2
#define CREATE_PROCESS_DEBUG_EVENT  3
#define EXIT_THREAD_DEBUG_EVENT     4
#define EXIT_PROCESS_DEBUG_EVENT    5
#define LOAD_DLL_DEBUG_EVENT	    6
#define UNLOAD_DLL_DEBUG_EVENT	    7
#define OUTPUT_DEBUG_STRING_EVENT   8
#define RIP_EVENT		    9

typedef struct {
  EXCEPTION_RECORD ExceptionRecord;
  DWORD dwFirstChance;
} EXCEPTION_DEBUG_INFO;

typedef struct {
  HANDLE hThread;
  LPVOID lpThreadLocalBase;
  LPTHREAD_START_ROUTINE lpStartAddress;
} CREATE_THREAD_DEBUG_INFO;

typedef struct {
    HANDLE	hFile;
    HANDLE	hProcess;
    HANDLE	hThread;
    LPVOID	lpBaseOfImage;
    DWORD	dwDebugInfoFileOffset;
    DWORD	nDebugInfoSize;
    LPVOID	lpThreadLocalBase;
    LPTHREAD_START_ROUTINE lpStartAddress;
    LPVOID	lpImageName;
    WORD	fUnicode;
} CREATE_PROCESS_DEBUG_INFO, *LPCREATE_PROCESS_DEBUG_INFO;

typedef struct {
  HANDLE hFile;
  void * lpBaseOfDll;
  DWORD dwDebugInfoFileOffset;
  DWORD nDebugInfoSize;
  void	* lpImageName;		/* pointer into target process space */
  WORD fUnicode;		/* I wonder what the 'f' stands for ;) */
} LOAD_DLL_DEBUG_INFO;

typedef struct {
    DWORD dwExitCode;
} EXIT_PROCESS_DEBUG_INFO;

typedef struct {
    DWORD dwExitCode;
} EXIT_THREAD_DEBUG_INFO;

typedef struct {
    LPVOID lpBaseOfDll;
} UNLOAD_DLL_DEBUG_INFO, *LPUNLOAD_DLL_DEBUG_INFO;

typedef struct {
    LPSTR lpDebugStringData;
    WORD fUnicode;
    WORD nDebugStringLength;
} OUTPUT_DEBUG_STRING_INFO, *LPOUTPUT_DEBUG_STRING_INFO;

typedef struct {
    DWORD dwError;
    DWORD dwType;
} RIP_INFO, *LPRIP_INFO;


typedef struct {
  DWORD dwDebugEventCode;
  DWORD dwProcessId;
  DWORD dwThreadId;
  union {
	  EXCEPTION_DEBUG_INFO Exception;
	  CREATE_THREAD_DEBUG_INFO CreateThread;
	  CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;
	  LOAD_DLL_DEBUG_INFO LoadDll;
	  EXIT_PROCESS_DEBUG_INFO ExitProcess;
	  EXIT_THREAD_DEBUG_INFO ExitThread;
	  UNLOAD_DLL_DEBUG_INFO UnloadDll;
	  OUTPUT_DEBUG_STRING_INFO DebugString;
	  RIP_INFO RipInfo;
	} u;
} DEBUG_EVENT, * LPDEBUG_EVENT;

#define DBG_CONTINUE			0x00010002
#define DBG_TERMINATE_THREAD		0x40010003
#define DBG_TERMINATE_PROCESS		0x40010004
#define DBG_CONTROL_C			0x40010005
#define DBG_CONTROL_BREAK		0x40010008
#define DBG_EXCEPTION_NOT_HANDLED	0x80010001

BOOL WINAPI ContinueDebugEvent (DWORD pid, DWORD hid, DWORD flags);
BOOL WINAPI DebugActiveProcess (DWORD pid);
VOID WINAPI DebugBreak(VOID);
BOOL WINAPI WaitForDebugEvent(LPDEBUG_EVENT lpDebugEvent,
    DWORD dwMilliseconds);


BOOL WINAPI ReadProcessMemory (HANDLE ph , LPCVOID addr,  void *, int, DWORD *);
BOOL WINAPI WriteProcessMemory (HANDLE ph , LPVOID addr, void *, int, DWORD *);

/* The doc refered me to winnt.h, so I had to look.. */
#define SIZE_OF_80387_REGISTERS      80

typedef struct {
    DWORD   ControlWord;
    DWORD   StatusWord;
    DWORD   TagWord;
    DWORD   ErrorOffset;
    DWORD   ErrorSelector;
    DWORD   DataOffset;
    DWORD   DataSelector;
    BYTE    RegisterArea[SIZE_OF_80387_REGISTERS];
    DWORD   Cr0NpxState;
} FLOATING_SAVE_AREA;

/* Values for contextflags */
#define CONTEXT_i386	0x10000

#define CONTEXT_CONTROL 	(CONTEXT_i386 | 1) /* SS:SP CS:IP FLAGS SS:BP */
#define CONTEXT_INTEGER 	(CONTEXT_i386 | 2) /* ABCD X SD I */
#define CONTEXT_SEGMENTS	(CONTEXT_i386 | 4) /* DEFS segs */
#define CONTEXT_FLOATING_POINT	(CONTEXT_i386 | 8) /* 387 state */
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x10)
#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)

typedef struct {
  DWORD ContextFlags;

  DWORD   Dr0;
  DWORD   Dr1;
  DWORD   Dr2;
  DWORD   Dr3;
  DWORD   Dr6;
  DWORD   Dr7;

  FLOATING_SAVE_AREA FloatSave;

  DWORD   SegGs;
  DWORD   SegFs;
  DWORD   SegEs;
  DWORD   SegDs;

  DWORD   Edi;
  DWORD   Esi;
  DWORD   Ebx;
  DWORD   Edx;
  DWORD   Ecx;
  DWORD   Eax;

  DWORD   Ebp;
  DWORD   Eip;
  DWORD   SegCs;
#define FLAG_TRACE_BIT 0x100
  DWORD   EFlags;
  DWORD   Esp;
  DWORD   SegSs;

} CONTEXT, *PCONTEXT;

BOOL WINAPI GetThreadContext(HANDLE threadh, CONTEXT *cont);
BOOL WINAPI SetThreadContext(HANDLE threadh, CONTEXT *cont);
BOOL WINAPI FlushInstructionCache(HANDLE process, DWORD p, DWORD len);

typedef struct {
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;

typedef LONG WINAPI (*PTOP_LEVEL_EXCEPTION_FILTER)(EXCEPTION_POINTERS *ExceptionInfo);
typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER);


typedef struct _LIST_ENTRY {
   struct _LIST_ENTRY	    *Flink;
   struct _LIST_ENTRY	    *Blink;
} LIST_ENTRY;
typedef LIST_ENTRY *PLIST_ENTRY;


typedef struct _rtl_critical_section {
    WORD		    Type;
    WORD		    CreatorBackTraceIndex;
    struct _rtl_critical_section *CriticalSection;
    LIST_ENTRY		    ProcessLocksList;
    DWORD		    EntryCount;
    DWORD		    ContentionCount;
    DWORD		    Depth;
    PVOID		    OwnerBackTrace[5];
} RTL_CRITICAL_SECTION_DEBUG,
* PRTL_CRITICAL_SECTION_DEBUG;

typedef struct {
    PRTL_CRITICAL_SECTION_DEBUG     DebugInfo;
    LONG			    LockCount;
    LONG			    RecursionCount;
    HANDLE			    OwningThread;
    HANDLE			    LockSemaphore;
    DWORD			    Reserved;
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;

typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
typedef RTL_CRITICAL_SECTION *LPCRITICAL_SECTION;
typedef RTL_CRITICAL_SECTION_DEBUG CRITICAL_SECTION_DEBUG;

VOID WINAPI InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
VOID WINAPI EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
VOID WINAPI LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
VOID WINAPI DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

#define CreateEvent TFUNCT(CreateEvent)
HANDLE WINAPI CreateEvent(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCTSTR);
#define OpenEvent TFUNCT(OpenEvent)
HANDLE WINAPI OpenEvent(DWORD, BOOL, LPCTSTR);
BOOL WINAPI SetEvent(HANDLE hEvent);
BOOL WINAPI ResetEvent(HANDLE hEvent);
BOOL WINAPI PulseEvent(HANDLE hEvent);

#define CreateMutex TFUNCT(CreateMutex)
HANDLE WINAPI CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,
	BOOL bInitialOwner, LPCTSTR lpName);
#define OpenMutex TFUNCT(OpenMutex)
HANDLE WINAPI OpenMutex(DWORD dwDesiredAccess, BOOL bInheritHandle,
	LPCTSTR lpName);
BOOL WINAPI ReleaseMutex(HANDLE hMutex);

#define CreateSemaphore TFUNCT(CreateSemaphore)
HANDLE WINAPI CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
	LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName);
#define OpenSemaphore TFUNCT(OpenSemaphore)
HANDLE WINAPI OpenSemaphore(DWORD dwDesiredAccess, BOOL bInheritHandle,
	LPCTSTR lpName);
BOOL WINAPI ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, 
	LPLONG lpPreviousCount);

#ifdef __cplusplus
}
#endif

#endif /* !defined (_WINPROC_H) */
