/*
 * Win32 kernel functions
 *
 * Copyright 1995 Martin von Loewis
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/times.h>
#include "windows.h"
#include "winerror.h"
#include "heap.h"
#include "thread.h"
#include "handle32.h"
#include "pe_image.h"
#include "file.h"
#include "stddebug.h"
#include "debug.h"

typedef struct {
	K32OBJ	header;
	DWORD	maxcount;
	DWORD	count;
	DWORD	initial;
} K32SEMAPHORE;

typedef struct {
	K32OBJ	header;
	THDB	*owning_thread; /* we are locked by this thread */
} K32MUTEX;

typedef struct {
	K32OBJ	header;
} K32EVENT;

/***********************************************************************
 *           CreateMutexA    (KERNEL32.52)
 */
HANDLE32 WINAPI CreateMutex32A(SECURITY_ATTRIBUTES *sa,BOOL32 on,LPCSTR name)
{
	K32MUTEX	*mut;
	HANDLE32	handle;
	K32OBJ 		*obj = K32OBJ_FindName( name );

	if (obj) {
		if (obj->type == K32OBJ_MUTEX) {
			SetLastError( ERROR_ALREADY_EXISTS );
			return PROCESS_AllocHandle( obj,0 );
		}
		SetLastError( ERROR_DUP_NAME );
		return 0;
	}
	mut = (K32MUTEX*)HeapAlloc(GetProcessHeap(),0,sizeof(K32MUTEX));
	mut->header.type = K32OBJ_MUTEX;
	mut->header.refcount  = 1;
	mut->owning_thread = NULL;
	if (name)
		K32OBJ_AddName(&(mut->header),name);
	handle = PROCESS_AllocHandle(&(mut->header),0);
	if (handle != INVALID_HANDLE_VALUE32) {
		if (on)
			mut->owning_thread = (THDB *)GetCurrentThreadId();
		return handle;
	}
	K32OBJ_DecCount(&(mut->header)); /* also frees name */
	HeapFree(GetProcessHeap(),0,mut);
	return 0;
}

/***********************************************************************
 *           CreateMutexW    (KERNEL32.53)
 */
HANDLE32 WINAPI CreateMutex32W(SECURITY_ATTRIBUTES *sa, BOOL32 on, LPCWSTR a)
{
	LPSTR		name = a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL;
	HANDLE32	ret;

	ret = CreateMutex32A(sa,on,name);
	if (name) HeapFree(GetProcessHeap(),0,name);
	return ret;
}

/***********************************************************************
 *           CreateSemaphoreA    (KERNEL32.60)
 */
HANDLE32 WINAPI CreateSemaphore32A( LPSECURITY_ATTRIBUTES sa,
                                    LONG initial,LONG max,LPCSTR name )
{
	K32SEMAPHORE	*sem;
	HANDLE32	handle;
	K32OBJ 		*obj = K32OBJ_FindName( name );

	if (obj) {
		if (obj->type == K32OBJ_SEMAPHORE) {
			SetLastError( ERROR_ALREADY_EXISTS );
			return PROCESS_AllocHandle( obj,0 );
		}
		SetLastError( ERROR_DUP_NAME );
		return 0;
	}
	sem = (K32SEMAPHORE*)HeapAlloc(GetProcessHeap(),0,sizeof(K32SEMAPHORE));
	sem->header.type = K32OBJ_SEMAPHORE;
	sem->header.refcount  = 1;

	sem->maxcount 	= max;
	sem->count	= initial;
	sem->initial	= initial;
	if (name)
		K32OBJ_AddName(&(sem->header),name);
	handle = PROCESS_AllocHandle(&(sem->header),0);
	if (handle != INVALID_HANDLE_VALUE32)
		return handle;
	K32OBJ_DecCount(&(sem->header)); /* also frees name */
	HeapFree(GetProcessHeap(),0,sem);
	return 0;
}

/***********************************************************************
 *           CreateSemaphoreW    (KERNEL32.61)
 */
HANDLE32 WINAPI CreateSemaphore32W(SECURITY_ATTRIBUTES *sa,LONG initial,LONG max,LPCWSTR a)
{
	LPSTR		name =a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL;
	HANDLE32	ret;

	ret = CreateSemaphore32A(sa,initial,max,name);
	if (a) HeapFree(GetProcessHeap(),0,name);
	return ret;
}


/***********************************************************************
 *           OpenSemaphoreA    (KERNEL32.403)
 */
HANDLE32 WINAPI OpenSemaphore32A(DWORD desired,BOOL32 inherit,LPCSTR name)
{
	K32OBJ 		*obj = K32OBJ_FindName( name );

	if (obj) {
		if (obj->type == K32OBJ_SEMAPHORE)
			return PROCESS_AllocHandle( obj,0 );
		SetLastError( ERROR_DUP_NAME );
		return 0;
	}
	return 0;
}

/***********************************************************************
 *           OpenSemaphoreA    (KERNEL32.404)
 */
HANDLE32 WINAPI OpenSemaphore32W(DWORD desired,BOOL32 inherit,LPCWSTR name)
{
	LPSTR	nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
	HANDLE32	ret = OpenSemaphore32A(desired,inherit,nameA);

	if (name) HeapFree(GetProcessHeap(),0,nameA);
	return ret;
}

/***********************************************************************
 *           ReleaseSemaphore    (KERNEL32.403)
 */
BOOL32 WINAPI ReleaseSemaphore(HANDLE32 hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount)
{
	K32SEMAPHORE	*sem;

	sem = (K32SEMAPHORE*)PROCESS_GetObjPtr(hSemaphore,K32OBJ_SEMAPHORE);
	if (!sem)
		return FALSE;
	if (lpPreviousCount) *lpPreviousCount = sem->count;
	sem->count += lReleaseCount;
	if (sem->count>sem->maxcount) {
		fprintf(stderr,"ReleaseSemaphore(%d,%ld,.), released more then possible??\n",hSemaphore,lReleaseCount);
		sem->count = sem->maxcount;
	}

	/* FIXME: wake up all threads blocked on that semaphore */

	K32OBJ_DecCount(&(sem->header));
	return TRUE;
}

/***********************************************************************
 *           OpenMutexA    (KERNEL32.399)
 */
HANDLE32 WINAPI OpenMutex32A(DWORD desiredaccess, BOOL32 inherithandle, LPCSTR name)
{
	K32OBJ 		*obj = K32OBJ_FindName( name );

	if (obj) {
		if (obj->type == K32OBJ_MUTEX)
			return PROCESS_AllocHandle( obj,0 );
		SetLastError( ERROR_DUP_NAME );
		return 0;
	}
	return 0;
}

/***********************************************************************
 *           OpenMutexW    (KERNEL32.400)
 */
HANDLE32 WINAPI OpenMutex32W(DWORD desiredaccess, BOOL32 inherithandle,
                             LPCWSTR name)
{
	LPSTR		nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
	HANDLE32	ret = OpenMutex32A(desiredaccess,inherithandle,nameA);

	if (name) HeapFree(GetProcessHeap(),0,nameA);
	return ret;
}

/***********************************************************************
 *           ReleaseMutex    (KERNEL32.435)
 */
BOOL32 WINAPI ReleaseMutex (HANDLE32 h)
{
	K32MUTEX	*mut = (K32MUTEX*)PROCESS_GetObjPtr(h,K32OBJ_MUTEX);

	if (!mut)
		return 0;
	if (mut->owning_thread != (THDB *)GetCurrentThreadId()) {
		/* set error ... */
		K32OBJ_DecCount(&(mut->header));
		return 0;
	}
	mut->owning_thread = NULL;

	/* FIXME: wake up all threads blocked on this mutex */

	K32OBJ_DecCount(&(mut->header));
	return TRUE;
}

/***********************************************************************
 *           CreateEventA    (KERNEL32.43)
 */
HANDLE32 WINAPI CreateEvent32A(SECURITY_ATTRIBUTES *sa,BOOL32 au,BOOL32 on,
                               LPCSTR name)
{
	K32EVENT	*evt;
	HANDLE32	handle;
	K32OBJ 		*obj = K32OBJ_FindName( name );

	if (obj) {
		if (obj->type == K32OBJ_EVENT) {
			SetLastError( ERROR_ALREADY_EXISTS );
			return PROCESS_AllocHandle( obj,0 );
		}
		SetLastError( ERROR_DUP_NAME );
		return 0;
	}
	evt = (K32EVENT*)HeapAlloc(GetProcessHeap(),0,sizeof(K32EVENT));
	evt->header.type = K32OBJ_EVENT;
	evt->header.refcount  = 1;
	if (name)
		K32OBJ_AddName(&(evt->header),name);
	handle = PROCESS_AllocHandle(&(evt->header),0);
	if (handle != INVALID_HANDLE_VALUE32)
		return handle;
	K32OBJ_DecCount(&(evt->header)); /* also frees name */
	HeapFree(GetProcessHeap(),0,evt);
	return 0;
}

/***********************************************************************
 *           CreateEventW    (KERNEL32.43)
 */
HANDLE32 WINAPI CreateEvent32W(SECURITY_ATTRIBUTES *sa, BOOL32 au,
                               BOOL32 on,LPCWSTR name)
{
	LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
	HANDLE32 ret = CreateEvent32A(sa,au,on,nameA);

	if (name) HeapFree(GetProcessHeap(),0,nameA);
	return ret;
}

/***********************************************************************
 *           OpenEventA    (KERNEL32.394)
 */
HANDLE32 WINAPI OpenEvent32A(DWORD desiredaccess,BOOL32 inherithandle,LPCSTR name)
{
	K32OBJ 		*obj = K32OBJ_FindName( name );

	if (obj) {
		if (obj->type == K32OBJ_EVENT)
			return PROCESS_AllocHandle( obj,0 );
		SetLastError( ERROR_DUP_NAME );
		return 0;
	}
	return 0;
}

/***********************************************************************
 *           OpenEventW    (KERNEL32.395)
 */
HANDLE32 WINAPI OpenEvent32W(DWORD desiredaccess,BOOL32 inherithandle,LPCWSTR name)
{
	LPSTR	nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
	HANDLE32	ret = OpenEvent32A(desiredaccess,inherithandle,nameA);

	if (name) HeapFree(GetProcessHeap(),0,nameA);
	return ret;
}

/***********************************************************************
 *           SetEvent    (KERNEL32.487)
 */
BOOL32 WINAPI SetEvent (HANDLE32 h)
{
	fprintf(stderr,"SetEvent(%d) stub\n",h);
	return 0;
}
/***********************************************************************
 *           ResetEvent    (KERNEL32.439)
 */
BOOL32 WINAPI ResetEvent (HANDLE32 h)
{
	fprintf(stderr,"ResetEvent(%d) stub\n",h);
	return 0;
}

/***********************************************************************
 *           WaitForSingleObject    (KERNEL32.561)
 */
DWORD WINAPI WaitForSingleObject(HANDLE32 h, DWORD timeout)
{
	fprintf(stderr,"WaitForSingleObject(%d,%ld) stub\n",h,timeout);
	return 0;
}

/***********************************************************************
 *           WaitForSingleObjectEx    (KERNEL32)
 */
DWORD WINAPI WaitForSingleObjectEx(HANDLE32 h,DWORD timeout,BOOL32 bAlertable)
{
	fprintf(stderr,"WaitForSingleObjectEx(%d,%ld,%d) stub\n",h,timeout,bAlertable);
	return 0;
}

/***********************************************************************
 *           MsgWaitForMultipleObjects    (USER32.399)
 */
DWORD WINAPI MsgWaitForMultipleObjects(
	DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds,
	DWORD dwWakeMask
) {
	int	i;
	fprintf(stderr,"MsgWaitForMultipleObjects(%ld,[",nCount);
	for (i=0;i<nCount;i++)
		fprintf(stderr,"%ld,",(DWORD)pHandles[i]);
	fprintf(stderr,"],%d,%ld,0x%08lx)\n",fWaitAll,dwMilliseconds,dwWakeMask);
	return 0;
}

/***********************************************************************
 *           WaitForMultipleObjects    (KERNEL32)
 */
DWORD WINAPI WaitForMultipleObjects(
	DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds
) {
	return MsgWaitForMultipleObjects(nCount,pHandles,fWaitAll,dwMilliseconds,0);
}

/***********************************************************************
 *           DuplicateHandle    (KERNEL32.78)
 */
BOOL32 WINAPI DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL32 f, DWORD g)
{
	fprintf(stderr,"DuplicateHandle(%d,%d,%d,%p,%ld,%d,%ld) stub\n",a,b,c,d,e,f,g);
	*d = b;
	return TRUE;
}

/**********************************************************************
 *          GetProcessAffinityMask
 */
BOOL32 WINAPI GetProcessAffinityMask(HANDLE32 hProcess,
                                     LPDWORD lpProcessAffinityMask,
                                     LPDWORD lpSystemAffinityMask)
{
	dprintf_task(stddeb,"GetProcessAffinityMask(%x,%lx,%lx)\n",
		hProcess,(lpProcessAffinityMask?*lpProcessAffinityMask:0),
		(lpSystemAffinityMask?*lpSystemAffinityMask:0));
	/* It is definitely important for a process to know on what processor
	   it is running :-) */
	if(lpProcessAffinityMask)
		*lpProcessAffinityMask=1;
	if(lpSystemAffinityMask)
		*lpSystemAffinityMask=1;
	return TRUE;
}

/**********************************************************************
 *           SetThreadAffinityMask
 * Works now like the Windows95 (no MP support) version
 */
BOOL32 WINAPI SetThreadAffinityMask(HANDLE32 hThread, DWORD dwThreadAffinityMask)
{
	THDB	*thdb = (THDB*)PROCESS_GetObjPtr(hThread,K32OBJ_THREAD);

	if (!thdb) 
		return FALSE;
	if (dwThreadAffinityMask!=1) {
		fprintf(stderr,"SetThreadAffinityMask(%d,%ld), only 1 processor supported.\n",(int)hThread,dwThreadAffinityMask);
		K32OBJ_DecCount((K32OBJ*)thdb);
		return FALSE;
	}
	K32OBJ_DecCount((K32OBJ*)thdb);
	return TRUE;
}

BOOL32 WINAPI CreateProcess32A(
	LPCSTR appname,LPSTR cmdline,LPSECURITY_ATTRIBUTES processattributes,
        LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles,
	DWORD creationflags,LPVOID env,LPCSTR curdir,
	LPSTARTUPINFO32A startupinfo,LPPROCESS_INFORMATION processinfo
) {
	fprintf(stderr,"CreateProcessA(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p), stub\n",
		appname,cmdline,processattributes,threadattributes,
		inherithandles,creationflags,env,curdir,startupinfo,processinfo
	);
	/* make from lcc uses system as fallback if CreateProcess returns
	   FALSE, so return false */
	return FALSE;
}

BOOL32 WINAPI CreateProcess32W(
	LPCWSTR appname,LPWSTR cmdline,LPSECURITY_ATTRIBUTES processattributes,
        LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles,
	DWORD creationflags,LPVOID env,LPCWSTR curdir,
	LPSTARTUPINFO32W startupinfo,LPPROCESS_INFORMATION processinfo)
{
    fprintf(stderr,"CreateProcessW(%p,%p,%p,%p,%d,%08lx,%p,%p,%p,%p) stub\n",
            appname,cmdline,processattributes,threadattributes,
            inherithandles,creationflags,env,curdir,startupinfo,processinfo );
    /* make from lcc uses system as fallback if CreateProcess returns
       FALSE, so return false */
    return FALSE;
}

BOOL32 WINAPI ContinueDebugEvent(DWORD pid,DWORD tid,DWORD contstatus) {
	fprintf(stderr,"ContinueDebugEvent(%ld,%ld,%ld) stub\n",pid,tid,contstatus);
	return TRUE;
}

/*********************************************************************
 *	GetProcessTimes				[KERNEL32.262]
 *
 * FIXME: implement this better ...
 */
BOOL32 WINAPI GetProcessTimes(
	HANDLE32 hprocess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,
	LPFILETIME lpKernelTime, LPFILETIME lpUserTime
) {
	struct tms tms;

	times(&tms);
	DOSFS_UnixTimeToFileTime(tms.tms_utime,lpUserTime,0);
	DOSFS_UnixTimeToFileTime(tms.tms_stime,lpKernelTime,0);
	return TRUE;
}

