/*
 * 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;
}


/***********************************************************************
 *           WaitForMultipleObjects    (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;
}
/***********************************************************************
 *           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;
}

HINSTANCE32 WINAPI LoadLibraryEx32A(LPCSTR libname,HFILE32 hfile,DWORD flags)
{
    fprintf(stderr,"LoadLibraryEx32A(%s,%d,0x%08lx)\n",libname,hfile,flags);
    return LoadLibrary32A(libname);
}

/***********************************************************************
 *           LoadLibraryA         (KERNEL32.365)
 * copied from LoadLibrary
 * This does not currently support built-in libraries
 */
HINSTANCE32 WINAPI LoadLibrary32A(LPCSTR libname)
{
	HINSTANCE32 handle;
	dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
	handle = LoadModule16( libname, (LPVOID)-1 );
	if (handle == (HINSTANCE32) -1)
	{
		char buffer[256];
		strcpy( buffer, libname );
		strcat( buffer, ".dll" );
		handle = LoadModule16( buffer, (LPVOID)-1 );
	}
	/* Obtain module handle and call initialization function */
#ifndef WINELIB
	if (handle >= (HINSTANCE32)32) PE_InitializeDLLs( GetExePtr(handle), DLL_PROCESS_ATTACH, NULL);
#endif
	return handle;
}

/***********************************************************************
 *           LoadLibrary32W         (KERNEL32.368)
 */
HINSTANCE32 WINAPI LoadLibrary32W(LPCWSTR libnameW)
{
    LPSTR libnameA = HEAP_strdupWtoA( GetProcessHeap(), 0, libnameW );
    HINSTANCE32 ret = LoadLibrary32A( libnameA );
    HeapFree( GetProcessHeap(), 0, libnameA );
    return ret;
}

/***********************************************************************
 *           FreeLibrary
 */
BOOL32 WINAPI FreeLibrary32(HINSTANCE32 hLibModule)
{
	fprintf(stderr,"FreeLibrary: empty stub\n");
	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,"CreateProcess(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p)\n",
		appname,cmdline,processattributes,threadattributes,
		inherithandles,creationflags,env,curdir,startupinfo,processinfo
	);
	return TRUE;
}

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;
}

