Release 970509
[wine/multimedia.git] / win32 / process.c
blob54baf23e425a24695a0899fd315f8cdbc4094760
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 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 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 CreateSemaphore32A(
88 LPSECURITY_ATTRIBUTES sa,LONG initial,LONG max,LPCSTR name
89 ) {
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 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 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 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 ReleaseSemaphore(HANDLE32 hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount) {
165 K32SEMAPHORE *sem;
167 sem = (K32SEMAPHORE*)PROCESS_GetObjPtr(hSemaphore,K32OBJ_SEMAPHORE);
168 if (!sem)
169 return FALSE;
170 if (lpPreviousCount) *lpPreviousCount = sem->count;
171 sem->count += lReleaseCount;
172 if (sem->count>sem->maxcount) {
173 fprintf(stderr,"ReleaseSemaphore(%d,%ld,.), released more then possible??\n",hSemaphore,lReleaseCount);
174 sem->count = sem->maxcount;
177 /* FIXME: wake up all threads blocked on that semaphore */
179 K32OBJ_DecCount(&(sem->header));
180 return TRUE;
183 /***********************************************************************
184 * OpenMutexA (KERNEL32.399)
186 HANDLE32 OpenMutex32A(DWORD desiredaccess, BOOL32 inherithandle, LPCSTR name)
188 K32OBJ *obj = K32OBJ_FindName( name );
190 if (obj) {
191 if (obj->type == K32OBJ_MUTEX)
192 return PROCESS_AllocHandle( obj,0 );
193 SetLastError( ERROR_DUP_NAME );
194 return 0;
196 return 0;
199 /***********************************************************************
200 * OpenMutexW (KERNEL32.400)
202 HANDLE32 OpenMutex32W(DWORD desiredaccess, BOOL32 inherithandle, LPCWSTR name)
204 LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
205 HANDLE32 ret = OpenMutex32A(desiredaccess,inherithandle,nameA);
207 if (name) HeapFree(GetProcessHeap(),0,nameA);
208 return ret;
211 /***********************************************************************
212 * ReleaseMutex (KERNEL32.435)
214 BOOL32 ReleaseMutex (HANDLE32 h)
216 K32MUTEX *mut = (K32MUTEX*)PROCESS_GetObjPtr(h,K32OBJ_MUTEX);
218 if (!mut)
219 return 0;
220 if (mut->owning_thread != (THDB *)GetCurrentThreadId()) {
221 /* set error ... */
222 K32OBJ_DecCount(&(mut->header));
223 return 0;
225 mut->owning_thread = NULL;
227 /* FIXME: wake up all threads blocked on this mutex */
229 K32OBJ_DecCount(&(mut->header));
230 return TRUE;
233 /***********************************************************************
234 * CreateEventA (KERNEL32.43)
236 HANDLE32 CreateEvent32A(SECURITY_ATTRIBUTES *sa,BOOL32 au,BOOL32 on,LPCSTR name)
238 K32EVENT *evt;
239 HANDLE32 handle;
240 K32OBJ *obj = K32OBJ_FindName( name );
242 if (obj) {
243 if (obj->type == K32OBJ_EVENT) {
244 SetLastError( ERROR_ALREADY_EXISTS );
245 return PROCESS_AllocHandle( obj,0 );
247 SetLastError( ERROR_DUP_NAME );
248 return 0;
250 evt = (K32EVENT*)HeapAlloc(GetProcessHeap(),0,sizeof(K32EVENT));
251 evt->header.type = K32OBJ_EVENT;
252 evt->header.refcount = 1;
253 if (name)
254 K32OBJ_AddName(&(evt->header),name);
255 handle = PROCESS_AllocHandle(&(evt->header),0);
256 if (handle != INVALID_HANDLE_VALUE32)
257 return handle;
258 K32OBJ_DecCount(&(evt->header)); /* also frees name */
259 HeapFree(GetProcessHeap(),0,evt);
260 return 0;
263 /***********************************************************************
264 * CreateEventW (KERNEL32.43)
266 HANDLE32 CreateEvent32W(SECURITY_ATTRIBUTES *sa, BOOL32 au, BOOL32 on,LPCWSTR name)
268 LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
269 HANDLE32 ret = CreateEvent32A(sa,au,on,nameA);
271 if (name) HeapFree(GetProcessHeap(),0,nameA);
272 return ret;
275 /***********************************************************************
276 * OpenEventA (KERNEL32.394)
278 HANDLE32 OpenEvent32A(DWORD desiredaccess,BOOL32 inherithandle,LPCSTR name) {
279 K32OBJ *obj = K32OBJ_FindName( name );
281 if (obj) {
282 if (obj->type == K32OBJ_EVENT)
283 return PROCESS_AllocHandle( obj,0 );
284 SetLastError( ERROR_DUP_NAME );
285 return 0;
287 return 0;
290 /***********************************************************************
291 * OpenEventW (KERNEL32.395)
293 HANDLE32 OpenEvent32W(DWORD desiredaccess,BOOL32 inherithandle,LPCWSTR name) {
294 LPSTR nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
295 HANDLE32 ret = OpenEvent32A(desiredaccess,inherithandle,nameA);
297 if (name) HeapFree(GetProcessHeap(),0,nameA);
298 return ret;
301 /***********************************************************************
302 * SetEvent (KERNEL32.487)
304 BOOL32 SetEvent (HANDLE32 h)
306 fprintf(stderr,"SetEvent(%d) stub\n",h);
307 return 0;
309 /***********************************************************************
310 * ResetEvent (KERNEL32.439)
312 BOOL32 ResetEvent (HANDLE32 h)
314 fprintf(stderr,"ResetEvent(%d) stub\n",h);
315 return 0;
318 /***********************************************************************
319 * WaitForSingleObject (KERNEL32.561)
321 DWORD WaitForSingleObject(HANDLE32 h, DWORD timeout)
323 fprintf(stderr,"WaitForSingleObject(%d,%ld) stub\n",h,timeout);
324 return 0;
327 /***********************************************************************
328 * WaitForSingleObject (USER32.399)
330 DWORD MsgWaitForMultipleObjects(
331 DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds,
332 DWORD dwWakeMask
334 int i;
335 fprintf(stderr,"MsgWaitForMultipleObjects(%ld,[",nCount);
336 for (i=0;i<nCount;i++)
337 fprintf(stderr,"%ld,",(DWORD)pHandles[i]);
338 fprintf(stderr,"],%d,%ld,0x%08lx)\n",fWaitAll,dwMilliseconds,dwWakeMask);
339 return 0;
341 /***********************************************************************
342 * DuplicateHandle (KERNEL32.78)
344 BOOL32 DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL32 f, DWORD g)
346 fprintf(stderr,"DuplicateHandle(%d,%d,%d,%p,%ld,%d,%ld) stub\n",a,b,c,d,e,f,g);
347 *d = b;
348 return TRUE;
352 /***********************************************************************
353 * LoadLibraryA (KERNEL32.365)
354 * copied from LoadLibrary
355 * This does not currently support built-in libraries
357 HINSTANCE32 LoadLibrary32A(LPCSTR libname)
359 HINSTANCE32 handle;
360 dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
361 handle = LoadModule16( libname, (LPVOID)-1 );
362 if (handle == (HINSTANCE32) -1)
364 char buffer[256];
365 strcpy( buffer, libname );
366 strcat( buffer, ".dll" );
367 handle = LoadModule16( buffer, (LPVOID)-1 );
369 /* Obtain module handle and call initialization function */
370 #ifndef WINELIB
371 if (handle >= (HINSTANCE32)32) PE_InitializeDLLs( GetExePtr(handle), DLL_PROCESS_ATTACH, NULL);
372 #endif
373 return handle;
376 /***********************************************************************
377 * LoadLibrary32W (KERNEL32.368)
379 HINSTANCE32 LoadLibrary32W(LPCWSTR libnameW)
381 LPSTR libnameA = HEAP_strdupWtoA( GetProcessHeap(), 0, libnameW );
382 HINSTANCE32 ret = LoadLibrary32A( libnameA );
383 HeapFree( GetProcessHeap(), 0, libnameA );
384 return ret;
387 /***********************************************************************
388 * FreeLibrary
390 BOOL32 FreeLibrary32(HINSTANCE32 hLibModule)
392 fprintf(stderr,"FreeLibrary: empty stub\n");
393 return TRUE;
396 /**********************************************************************
397 * GetProcessAffinityMask
399 BOOL32 GetProcessAffinityMask(HANDLE32 hProcess, LPDWORD lpProcessAffinityMask,
400 LPDWORD lpSystemAffinityMask)
402 dprintf_task(stddeb,"GetProcessAffinityMask(%x,%lx,%lx)\n",
403 hProcess,(lpProcessAffinityMask?*lpProcessAffinityMask:0),
404 (lpSystemAffinityMask?*lpSystemAffinityMask:0));
405 /* It is definitely important for a process to know on what processor
406 it is running :-) */
407 if(lpProcessAffinityMask)
408 *lpProcessAffinityMask=1;
409 if(lpSystemAffinityMask)
410 *lpSystemAffinityMask=1;
411 return TRUE;
414 /**********************************************************************
415 * SetThreadAffinityMask
416 * Works now like the Windows95 (no MP support) version
418 BOOL32 SetThreadAffinityMask(HANDLE32 hThread, DWORD dwThreadAffinityMask)
420 THDB *thdb = (THDB*)PROCESS_GetObjPtr(hThread,K32OBJ_THREAD);
422 if (!thdb)
423 return FALSE;
424 if (dwThreadAffinityMask!=1) {
425 fprintf(stderr,"SetThreadAffinityMask(%d,%ld), only 1 processor supported.\n",(int)hThread,dwThreadAffinityMask);
426 K32OBJ_DecCount((K32OBJ*)thdb);
427 return FALSE;
429 K32OBJ_DecCount((K32OBJ*)thdb);
430 return TRUE;
433 BOOL32
434 CreateProcess32A(
435 LPCSTR appname,LPSTR cmdline,LPSECURITY_ATTRIBUTES processattributes,
436 LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles,
437 DWORD creationflags,LPVOID env,LPCSTR curdir,
438 LPSTARTUPINFO32A startupinfo,LPPROCESS_INFORMATION processinfo
440 fprintf(stderr,"CreateProcess(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p)\n",
441 appname,cmdline,processattributes,threadattributes,
442 inherithandles,creationflags,env,curdir,startupinfo,processinfo
444 return TRUE;
447 BOOL32
448 ContinueDebugEvent(DWORD pid,DWORD tid,DWORD contstatus) {
449 fprintf(stderr,"ContinueDebugEvent(%ld,%ld,%ld), stub\n",pid,tid,contstatus);
450 return TRUE;
453 /*********************************************************************
454 * GetProcessTimes [KERNEL32.262]
456 * FIXME: implement this better ...
458 BOOL32
459 GetProcessTimes(
460 HANDLE32 hprocess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,
461 LPFILETIME lpKernelTime, LPFILETIME lpUserTime
463 struct tms tms;
465 times(&tms);
466 DOSFS_UnixTimeToFileTime(tms.tms_utime,lpUserTime,0);
467 DOSFS_UnixTimeToFileTime(tms.tms_stime,lpKernelTime,0);
468 return TRUE;