Release 970824
[wine/multimedia.git] / win32 / process.c
blobff4f2c5bc989aeff945425020f72ecedbc26ef40
1 /*
2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis
5 */
7 #include <stdio.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <sys/times.h>
11 #include "windows.h"
12 #include "winerror.h"
13 #include "heap.h"
14 #include "thread.h"
15 #include "handle32.h"
16 #include "pe_image.h"
17 #include "file.h"
18 #include "stddebug.h"
19 #include "debug.h"
21 typedef struct {
22 K32OBJ header;
23 DWORD maxcount;
24 DWORD count;
25 DWORD initial;
26 } K32SEMAPHORE;
28 typedef struct {
29 K32OBJ header;
30 THDB *owning_thread; /* we are locked by this thread */
31 } K32MUTEX;
33 typedef struct {
34 K32OBJ header;
35 } K32EVENT;
37 /***********************************************************************
38 * CreateMutexA (KERNEL32.52)
40 HANDLE32 WINAPI CreateMutex32A(SECURITY_ATTRIBUTES *sa,BOOL32 on,LPCSTR name)
42 K32MUTEX *mut;
43 HANDLE32 handle;
44 K32OBJ *obj = K32OBJ_FindName( name );
46 if (obj) {
47 if (obj->type == K32OBJ_MUTEX) {
48 SetLastError( ERROR_ALREADY_EXISTS );
49 return PROCESS_AllocHandle( obj,0 );
51 SetLastError( ERROR_DUP_NAME );
52 return 0;
54 mut = (K32MUTEX*)HeapAlloc(GetProcessHeap(),0,sizeof(K32MUTEX));
55 mut->header.type = K32OBJ_MUTEX;
56 mut->header.refcount = 1;
57 mut->owning_thread = NULL;
58 if (name)
59 K32OBJ_AddName(&(mut->header),name);
60 handle = PROCESS_AllocHandle(&(mut->header),0);
61 if (handle != INVALID_HANDLE_VALUE32) {
62 if (on)
63 mut->owning_thread = (THDB *)GetCurrentThreadId();
64 return handle;
66 K32OBJ_DecCount(&(mut->header)); /* also frees name */
67 HeapFree(GetProcessHeap(),0,mut);
68 return 0;
71 /***********************************************************************
72 * CreateMutexW (KERNEL32.53)
74 HANDLE32 WINAPI CreateMutex32W(SECURITY_ATTRIBUTES *sa, BOOL32 on, LPCWSTR a)
76 LPSTR name = a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL;
77 HANDLE32 ret;
79 ret = CreateMutex32A(sa,on,name);
80 if (name) HeapFree(GetProcessHeap(),0,name);
81 return ret;
84 /***********************************************************************
85 * CreateSemaphoreA (KERNEL32.60)
87 HANDLE32 WINAPI CreateSemaphore32A( LPSECURITY_ATTRIBUTES sa,
88 LONG initial,LONG max,LPCSTR name )
90 K32SEMAPHORE *sem;
91 HANDLE32 handle;
92 K32OBJ *obj = K32OBJ_FindName( name );
94 if (obj) {
95 if (obj->type == K32OBJ_SEMAPHORE) {
96 SetLastError( ERROR_ALREADY_EXISTS );
97 return PROCESS_AllocHandle( obj,0 );
99 SetLastError( ERROR_DUP_NAME );
100 return 0;
102 sem = (K32SEMAPHORE*)HeapAlloc(GetProcessHeap(),0,sizeof(K32SEMAPHORE));
103 sem->header.type = K32OBJ_SEMAPHORE;
104 sem->header.refcount = 1;
106 sem->maxcount = max;
107 sem->count = initial;
108 sem->initial = initial;
109 if (name)
110 K32OBJ_AddName(&(sem->header),name);
111 handle = PROCESS_AllocHandle(&(sem->header),0);
112 if (handle != INVALID_HANDLE_VALUE32)
113 return handle;
114 K32OBJ_DecCount(&(sem->header)); /* also frees name */
115 HeapFree(GetProcessHeap(),0,sem);
116 return 0;
119 /***********************************************************************
120 * CreateSemaphoreW (KERNEL32.61)
122 HANDLE32 WINAPI CreateSemaphore32W(SECURITY_ATTRIBUTES *sa,LONG initial,LONG max,LPCWSTR a)
124 LPSTR name =a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL;
125 HANDLE32 ret;
127 ret = CreateSemaphore32A(sa,initial,max,name);
128 if (a) HeapFree(GetProcessHeap(),0,name);
129 return ret;
133 /***********************************************************************
134 * OpenSemaphoreA (KERNEL32.403)
136 HANDLE32 WINAPI OpenSemaphore32A(DWORD desired,BOOL32 inherit,LPCSTR name)
138 K32OBJ *obj = K32OBJ_FindName( name );
140 if (obj) {
141 if (obj->type == K32OBJ_SEMAPHORE)
142 return PROCESS_AllocHandle( obj,0 );
143 SetLastError( ERROR_DUP_NAME );
144 return 0;
146 return 0;
149 /***********************************************************************
150 * OpenSemaphoreA (KERNEL32.404)
152 HANDLE32 WINAPI OpenSemaphore32W(DWORD desired,BOOL32 inherit,LPCWSTR name)
154 LPSTR nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
155 HANDLE32 ret = OpenSemaphore32A(desired,inherit,nameA);
157 if (name) HeapFree(GetProcessHeap(),0,nameA);
158 return ret;
161 /***********************************************************************
162 * ReleaseSemaphore (KERNEL32.403)
164 BOOL32 WINAPI ReleaseSemaphore(HANDLE32 hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount)
166 K32SEMAPHORE *sem;
168 sem = (K32SEMAPHORE*)PROCESS_GetObjPtr(hSemaphore,K32OBJ_SEMAPHORE);
169 if (!sem)
170 return FALSE;
171 if (lpPreviousCount) *lpPreviousCount = sem->count;
172 sem->count += lReleaseCount;
173 if (sem->count>sem->maxcount) {
174 fprintf(stderr,"ReleaseSemaphore(%d,%ld,.), released more then possible??\n",hSemaphore,lReleaseCount);
175 sem->count = sem->maxcount;
178 /* FIXME: wake up all threads blocked on that semaphore */
180 K32OBJ_DecCount(&(sem->header));
181 return TRUE;
184 /***********************************************************************
185 * OpenMutexA (KERNEL32.399)
187 HANDLE32 WINAPI OpenMutex32A(DWORD desiredaccess, BOOL32 inherithandle, LPCSTR name)
189 K32OBJ *obj = K32OBJ_FindName( name );
191 if (obj) {
192 if (obj->type == K32OBJ_MUTEX)
193 return PROCESS_AllocHandle( obj,0 );
194 SetLastError( ERROR_DUP_NAME );
195 return 0;
197 return 0;
200 /***********************************************************************
201 * OpenMutexW (KERNEL32.400)
203 HANDLE32 WINAPI OpenMutex32W(DWORD desiredaccess, BOOL32 inherithandle,
204 LPCWSTR name)
206 LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
207 HANDLE32 ret = OpenMutex32A(desiredaccess,inherithandle,nameA);
209 if (name) HeapFree(GetProcessHeap(),0,nameA);
210 return ret;
213 /***********************************************************************
214 * ReleaseMutex (KERNEL32.435)
216 BOOL32 WINAPI ReleaseMutex (HANDLE32 h)
218 K32MUTEX *mut = (K32MUTEX*)PROCESS_GetObjPtr(h,K32OBJ_MUTEX);
220 if (!mut)
221 return 0;
222 if (mut->owning_thread != (THDB *)GetCurrentThreadId()) {
223 /* set error ... */
224 K32OBJ_DecCount(&(mut->header));
225 return 0;
227 mut->owning_thread = NULL;
229 /* FIXME: wake up all threads blocked on this mutex */
231 K32OBJ_DecCount(&(mut->header));
232 return TRUE;
235 /***********************************************************************
236 * CreateEventA (KERNEL32.43)
238 HANDLE32 WINAPI CreateEvent32A(SECURITY_ATTRIBUTES *sa,BOOL32 au,BOOL32 on,
239 LPCSTR name)
241 K32EVENT *evt;
242 HANDLE32 handle;
243 K32OBJ *obj = K32OBJ_FindName( name );
245 if (obj) {
246 if (obj->type == K32OBJ_EVENT) {
247 SetLastError( ERROR_ALREADY_EXISTS );
248 return PROCESS_AllocHandle( obj,0 );
250 SetLastError( ERROR_DUP_NAME );
251 return 0;
253 evt = (K32EVENT*)HeapAlloc(GetProcessHeap(),0,sizeof(K32EVENT));
254 evt->header.type = K32OBJ_EVENT;
255 evt->header.refcount = 1;
256 if (name)
257 K32OBJ_AddName(&(evt->header),name);
258 handle = PROCESS_AllocHandle(&(evt->header),0);
259 if (handle != INVALID_HANDLE_VALUE32)
260 return handle;
261 K32OBJ_DecCount(&(evt->header)); /* also frees name */
262 HeapFree(GetProcessHeap(),0,evt);
263 return 0;
266 /***********************************************************************
267 * CreateEventW (KERNEL32.43)
269 HANDLE32 WINAPI CreateEvent32W(SECURITY_ATTRIBUTES *sa, BOOL32 au,
270 BOOL32 on,LPCWSTR name)
272 LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
273 HANDLE32 ret = CreateEvent32A(sa,au,on,nameA);
275 if (name) HeapFree(GetProcessHeap(),0,nameA);
276 return ret;
279 /***********************************************************************
280 * OpenEventA (KERNEL32.394)
282 HANDLE32 WINAPI OpenEvent32A(DWORD desiredaccess,BOOL32 inherithandle,LPCSTR name)
284 K32OBJ *obj = K32OBJ_FindName( name );
286 if (obj) {
287 if (obj->type == K32OBJ_EVENT)
288 return PROCESS_AllocHandle( obj,0 );
289 SetLastError( ERROR_DUP_NAME );
290 return 0;
292 return 0;
295 /***********************************************************************
296 * OpenEventW (KERNEL32.395)
298 HANDLE32 WINAPI OpenEvent32W(DWORD desiredaccess,BOOL32 inherithandle,LPCWSTR name)
300 LPSTR nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
301 HANDLE32 ret = OpenEvent32A(desiredaccess,inherithandle,nameA);
303 if (name) HeapFree(GetProcessHeap(),0,nameA);
304 return ret;
307 /***********************************************************************
308 * SetEvent (KERNEL32.487)
310 BOOL32 WINAPI SetEvent (HANDLE32 h)
312 fprintf(stderr,"SetEvent(%d) stub\n",h);
313 return 0;
315 /***********************************************************************
316 * ResetEvent (KERNEL32.439)
318 BOOL32 WINAPI ResetEvent (HANDLE32 h)
320 fprintf(stderr,"ResetEvent(%d) stub\n",h);
321 return 0;
324 /***********************************************************************
325 * WaitForSingleObject (KERNEL32.561)
327 DWORD WINAPI WaitForSingleObject(HANDLE32 h, DWORD timeout)
329 fprintf(stderr,"WaitForSingleObject(%d,%ld) stub\n",h,timeout);
330 return 0;
333 /***********************************************************************
334 * WaitForSingleObjectEx (KERNEL32)
336 DWORD WINAPI WaitForSingleObjectEx(HANDLE32 h,DWORD timeout,BOOL32 bAlertable)
338 fprintf(stderr,"WaitForSingleObjectEx(%d,%ld,%d) stub\n",h,timeout,bAlertable);
339 return 0;
343 /***********************************************************************
344 * WaitForMultipleObjects (USER32.399)
346 DWORD WINAPI MsgWaitForMultipleObjects(
347 DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds,
348 DWORD dwWakeMask
350 int i;
351 fprintf(stderr,"MsgWaitForMultipleObjects(%ld,[",nCount);
352 for (i=0;i<nCount;i++)
353 fprintf(stderr,"%ld,",(DWORD)pHandles[i]);
354 fprintf(stderr,"],%d,%ld,0x%08lx)\n",fWaitAll,dwMilliseconds,dwWakeMask);
355 return 0;
357 /***********************************************************************
358 * DuplicateHandle (KERNEL32.78)
360 BOOL32 WINAPI DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL32 f, DWORD g)
362 fprintf(stderr,"DuplicateHandle(%d,%d,%d,%p,%ld,%d,%ld) stub\n",a,b,c,d,e,f,g);
363 *d = b;
364 return TRUE;
367 HINSTANCE32 WINAPI LoadLibraryEx32A(LPCSTR libname,HFILE32 hfile,DWORD flags)
369 fprintf(stderr,"LoadLibraryEx32A(%s,%d,0x%08lx)\n",libname,hfile,flags);
370 return LoadLibrary32A(libname);
373 /***********************************************************************
374 * LoadLibraryA (KERNEL32.365)
375 * copied from LoadLibrary
376 * This does not currently support built-in libraries
378 HINSTANCE32 WINAPI LoadLibrary32A(LPCSTR libname)
380 HINSTANCE32 handle;
381 dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
382 handle = LoadModule16( libname, (LPVOID)-1 );
383 if (handle == (HINSTANCE32) -1)
385 char buffer[256];
386 strcpy( buffer, libname );
387 strcat( buffer, ".dll" );
388 handle = LoadModule16( buffer, (LPVOID)-1 );
390 /* Obtain module handle and call initialization function */
391 #ifndef WINELIB
392 if (handle >= (HINSTANCE32)32) PE_InitializeDLLs( GetExePtr(handle), DLL_PROCESS_ATTACH, NULL);
393 #endif
394 return handle;
397 /***********************************************************************
398 * LoadLibrary32W (KERNEL32.368)
400 HINSTANCE32 WINAPI LoadLibrary32W(LPCWSTR libnameW)
402 LPSTR libnameA = HEAP_strdupWtoA( GetProcessHeap(), 0, libnameW );
403 HINSTANCE32 ret = LoadLibrary32A( libnameA );
404 HeapFree( GetProcessHeap(), 0, libnameA );
405 return ret;
408 /***********************************************************************
409 * FreeLibrary
411 BOOL32 WINAPI FreeLibrary32(HINSTANCE32 hLibModule)
413 fprintf(stderr,"FreeLibrary: empty stub\n");
414 return TRUE;
417 /**********************************************************************
418 * GetProcessAffinityMask
420 BOOL32 WINAPI GetProcessAffinityMask(HANDLE32 hProcess,
421 LPDWORD lpProcessAffinityMask,
422 LPDWORD lpSystemAffinityMask)
424 dprintf_task(stddeb,"GetProcessAffinityMask(%x,%lx,%lx)\n",
425 hProcess,(lpProcessAffinityMask?*lpProcessAffinityMask:0),
426 (lpSystemAffinityMask?*lpSystemAffinityMask:0));
427 /* It is definitely important for a process to know on what processor
428 it is running :-) */
429 if(lpProcessAffinityMask)
430 *lpProcessAffinityMask=1;
431 if(lpSystemAffinityMask)
432 *lpSystemAffinityMask=1;
433 return TRUE;
436 /**********************************************************************
437 * SetThreadAffinityMask
438 * Works now like the Windows95 (no MP support) version
440 BOOL32 WINAPI SetThreadAffinityMask(HANDLE32 hThread, DWORD dwThreadAffinityMask)
442 THDB *thdb = (THDB*)PROCESS_GetObjPtr(hThread,K32OBJ_THREAD);
444 if (!thdb)
445 return FALSE;
446 if (dwThreadAffinityMask!=1) {
447 fprintf(stderr,"SetThreadAffinityMask(%d,%ld), only 1 processor supported.\n",(int)hThread,dwThreadAffinityMask);
448 K32OBJ_DecCount((K32OBJ*)thdb);
449 return FALSE;
451 K32OBJ_DecCount((K32OBJ*)thdb);
452 return TRUE;
455 BOOL32 WINAPI CreateProcess32A(
456 LPCSTR appname,LPSTR cmdline,LPSECURITY_ATTRIBUTES processattributes,
457 LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles,
458 DWORD creationflags,LPVOID env,LPCSTR curdir,
459 LPSTARTUPINFO32A startupinfo,LPPROCESS_INFORMATION processinfo
461 fprintf(stderr,"CreateProcess(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p)\n",
462 appname,cmdline,processattributes,threadattributes,
463 inherithandles,creationflags,env,curdir,startupinfo,processinfo
465 return TRUE;
468 BOOL32 WINAPI ContinueDebugEvent(DWORD pid,DWORD tid,DWORD contstatus) {
469 fprintf(stderr,"ContinueDebugEvent(%ld,%ld,%ld), stub\n",pid,tid,contstatus);
470 return TRUE;
473 /*********************************************************************
474 * GetProcessTimes [KERNEL32.262]
476 * FIXME: implement this better ...
478 BOOL32 WINAPI GetProcessTimes(
479 HANDLE32 hprocess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,
480 LPFILETIME lpKernelTime, LPFILETIME lpUserTime
482 struct tms tms;
484 times(&tms);
485 DOSFS_UnixTimeToFileTime(tms.tms_utime,lpUserTime,0);
486 DOSFS_UnixTimeToFileTime(tms.tms_stime,lpKernelTime,0);
487 return TRUE;