Release 970914
[wine] / win32 / process.c
1 /*
2  * Win32 kernel functions
3  *
4  * Copyright 1995 Martin von Loewis
5  */
6
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"
20
21 typedef struct {
22         K32OBJ  header;
23         DWORD   maxcount;
24         DWORD   count;
25         DWORD   initial;
26 } K32SEMAPHORE;
27
28 typedef struct {
29         K32OBJ  header;
30         THDB    *owning_thread; /* we are locked by this thread */
31 } K32MUTEX;
32
33 typedef struct {
34         K32OBJ  header;
35 } K32EVENT;
36
37 /***********************************************************************
38  *           CreateMutexA    (KERNEL32.52)
39  */
40 HANDLE32 WINAPI CreateMutex32A(SECURITY_ATTRIBUTES *sa,BOOL32 on,LPCSTR name)
41 {
42         K32MUTEX        *mut;
43         HANDLE32        handle;
44         K32OBJ          *obj = K32OBJ_FindName( name );
45
46         if (obj) {
47                 if (obj->type == K32OBJ_MUTEX) {
48                         SetLastError( ERROR_ALREADY_EXISTS );
49                         return PROCESS_AllocHandle( obj,0 );
50                 }
51                 SetLastError( ERROR_DUP_NAME );
52                 return 0;
53         }
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;
65         }
66         K32OBJ_DecCount(&(mut->header)); /* also frees name */
67         HeapFree(GetProcessHeap(),0,mut);
68         return 0;
69 }
70
71 /***********************************************************************
72  *           CreateMutexW    (KERNEL32.53)
73  */
74 HANDLE32 WINAPI CreateMutex32W(SECURITY_ATTRIBUTES *sa, BOOL32 on, LPCWSTR a)
75 {
76         LPSTR           name = a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL;
77         HANDLE32        ret;
78
79         ret = CreateMutex32A(sa,on,name);
80         if (name) HeapFree(GetProcessHeap(),0,name);
81         return ret;
82 }
83
84 /***********************************************************************
85  *           CreateSemaphoreA    (KERNEL32.60)
86  */
87 HANDLE32 WINAPI CreateSemaphore32A( LPSECURITY_ATTRIBUTES sa,
88                                     LONG initial,LONG max,LPCSTR name )
89 {
90         K32SEMAPHORE    *sem;
91         HANDLE32        handle;
92         K32OBJ          *obj = K32OBJ_FindName( name );
93
94         if (obj) {
95                 if (obj->type == K32OBJ_SEMAPHORE) {
96                         SetLastError( ERROR_ALREADY_EXISTS );
97                         return PROCESS_AllocHandle( obj,0 );
98                 }
99                 SetLastError( ERROR_DUP_NAME );
100                 return 0;
101         }
102         sem = (K32SEMAPHORE*)HeapAlloc(GetProcessHeap(),0,sizeof(K32SEMAPHORE));
103         sem->header.type = K32OBJ_SEMAPHORE;
104         sem->header.refcount  = 1;
105
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;
117 }
118
119 /***********************************************************************
120  *           CreateSemaphoreW    (KERNEL32.61)
121  */
122 HANDLE32 WINAPI CreateSemaphore32W(SECURITY_ATTRIBUTES *sa,LONG initial,LONG max,LPCWSTR a)
123 {
124         LPSTR           name =a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL;
125         HANDLE32        ret;
126
127         ret = CreateSemaphore32A(sa,initial,max,name);
128         if (a) HeapFree(GetProcessHeap(),0,name);
129         return ret;
130 }
131
132
133 /***********************************************************************
134  *           OpenSemaphoreA    (KERNEL32.403)
135  */
136 HANDLE32 WINAPI OpenSemaphore32A(DWORD desired,BOOL32 inherit,LPCSTR name)
137 {
138         K32OBJ          *obj = K32OBJ_FindName( name );
139
140         if (obj) {
141                 if (obj->type == K32OBJ_SEMAPHORE)
142                         return PROCESS_AllocHandle( obj,0 );
143                 SetLastError( ERROR_DUP_NAME );
144                 return 0;
145         }
146         return 0;
147 }
148
149 /***********************************************************************
150  *           OpenSemaphoreA    (KERNEL32.404)
151  */
152 HANDLE32 WINAPI OpenSemaphore32W(DWORD desired,BOOL32 inherit,LPCWSTR name)
153 {
154         LPSTR   nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
155         HANDLE32        ret = OpenSemaphore32A(desired,inherit,nameA);
156
157         if (name) HeapFree(GetProcessHeap(),0,nameA);
158         return ret;
159 }
160
161 /***********************************************************************
162  *           ReleaseSemaphore    (KERNEL32.403)
163  */
164 BOOL32 WINAPI ReleaseSemaphore(HANDLE32 hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount)
165 {
166         K32SEMAPHORE    *sem;
167
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;
176         }
177
178         /* FIXME: wake up all threads blocked on that semaphore */
179
180         K32OBJ_DecCount(&(sem->header));
181         return TRUE;
182 }
183
184 /***********************************************************************
185  *           OpenMutexA    (KERNEL32.399)
186  */
187 HANDLE32 WINAPI OpenMutex32A(DWORD desiredaccess, BOOL32 inherithandle, LPCSTR name)
188 {
189         K32OBJ          *obj = K32OBJ_FindName( name );
190
191         if (obj) {
192                 if (obj->type == K32OBJ_MUTEX)
193                         return PROCESS_AllocHandle( obj,0 );
194                 SetLastError( ERROR_DUP_NAME );
195                 return 0;
196         }
197         return 0;
198 }
199
200 /***********************************************************************
201  *           OpenMutexW    (KERNEL32.400)
202  */
203 HANDLE32 WINAPI OpenMutex32W(DWORD desiredaccess, BOOL32 inherithandle,
204                              LPCWSTR name)
205 {
206         LPSTR           nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
207         HANDLE32        ret = OpenMutex32A(desiredaccess,inherithandle,nameA);
208
209         if (name) HeapFree(GetProcessHeap(),0,nameA);
210         return ret;
211 }
212
213 /***********************************************************************
214  *           ReleaseMutex    (KERNEL32.435)
215  */
216 BOOL32 WINAPI ReleaseMutex (HANDLE32 h)
217 {
218         K32MUTEX        *mut = (K32MUTEX*)PROCESS_GetObjPtr(h,K32OBJ_MUTEX);
219
220         if (!mut)
221                 return 0;
222         if (mut->owning_thread != (THDB *)GetCurrentThreadId()) {
223                 /* set error ... */
224                 K32OBJ_DecCount(&(mut->header));
225                 return 0;
226         }
227         mut->owning_thread = NULL;
228
229         /* FIXME: wake up all threads blocked on this mutex */
230
231         K32OBJ_DecCount(&(mut->header));
232         return TRUE;
233 }
234
235 /***********************************************************************
236  *           CreateEventA    (KERNEL32.43)
237  */
238 HANDLE32 WINAPI CreateEvent32A(SECURITY_ATTRIBUTES *sa,BOOL32 au,BOOL32 on,
239                                LPCSTR name)
240 {
241         K32EVENT        *evt;
242         HANDLE32        handle;
243         K32OBJ          *obj = K32OBJ_FindName( name );
244
245         if (obj) {
246                 if (obj->type == K32OBJ_EVENT) {
247                         SetLastError( ERROR_ALREADY_EXISTS );
248                         return PROCESS_AllocHandle( obj,0 );
249                 }
250                 SetLastError( ERROR_DUP_NAME );
251                 return 0;
252         }
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;
264 }
265
266 /***********************************************************************
267  *           CreateEventW    (KERNEL32.43)
268  */
269 HANDLE32 WINAPI CreateEvent32W(SECURITY_ATTRIBUTES *sa, BOOL32 au,
270                                BOOL32 on,LPCWSTR name)
271 {
272         LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
273         HANDLE32 ret = CreateEvent32A(sa,au,on,nameA);
274
275         if (name) HeapFree(GetProcessHeap(),0,nameA);
276         return ret;
277 }
278
279 /***********************************************************************
280  *           OpenEventA    (KERNEL32.394)
281  */
282 HANDLE32 WINAPI OpenEvent32A(DWORD desiredaccess,BOOL32 inherithandle,LPCSTR name)
283 {
284         K32OBJ          *obj = K32OBJ_FindName( name );
285
286         if (obj) {
287                 if (obj->type == K32OBJ_EVENT)
288                         return PROCESS_AllocHandle( obj,0 );
289                 SetLastError( ERROR_DUP_NAME );
290                 return 0;
291         }
292         return 0;
293 }
294
295 /***********************************************************************
296  *           OpenEventW    (KERNEL32.395)
297  */
298 HANDLE32 WINAPI OpenEvent32W(DWORD desiredaccess,BOOL32 inherithandle,LPCWSTR name)
299 {
300         LPSTR   nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
301         HANDLE32        ret = OpenEvent32A(desiredaccess,inherithandle,nameA);
302
303         if (name) HeapFree(GetProcessHeap(),0,nameA);
304         return ret;
305 }
306
307 /***********************************************************************
308  *           SetEvent    (KERNEL32.487)
309  */
310 BOOL32 WINAPI SetEvent (HANDLE32 h)
311 {
312         fprintf(stderr,"SetEvent(%d) stub\n",h);
313         return 0;
314 }
315 /***********************************************************************
316  *           ResetEvent    (KERNEL32.439)
317  */
318 BOOL32 WINAPI ResetEvent (HANDLE32 h)
319 {
320         fprintf(stderr,"ResetEvent(%d) stub\n",h);
321         return 0;
322 }
323
324 /***********************************************************************
325  *           WaitForSingleObject    (KERNEL32.561)
326  */
327 DWORD WINAPI WaitForSingleObject(HANDLE32 h, DWORD timeout)
328 {
329         fprintf(stderr,"WaitForSingleObject(%d,%ld) stub\n",h,timeout);
330         return 0;
331 }
332
333 /***********************************************************************
334  *           WaitForSingleObjectEx    (KERNEL32)
335  */
336 DWORD WINAPI WaitForSingleObjectEx(HANDLE32 h,DWORD timeout,BOOL32 bAlertable)
337 {
338         fprintf(stderr,"WaitForSingleObjectEx(%d,%ld,%d) stub\n",h,timeout,bAlertable);
339         return 0;
340 }
341
342
343 /***********************************************************************
344  *           WaitForMultipleObjects    (USER32.399)
345  */
346 DWORD WINAPI MsgWaitForMultipleObjects(
347         DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds,
348         DWORD dwWakeMask
349 ) {
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;
356 }
357 /***********************************************************************
358  *           DuplicateHandle    (KERNEL32.78)
359  */
360 BOOL32 WINAPI DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL32 f, DWORD g)
361 {
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;
365 }
366
367 /**********************************************************************
368  *          GetProcessAffinityMask
369  */
370 BOOL32 WINAPI GetProcessAffinityMask(HANDLE32 hProcess,
371                                      LPDWORD lpProcessAffinityMask,
372                                      LPDWORD lpSystemAffinityMask)
373 {
374         dprintf_task(stddeb,"GetProcessAffinityMask(%x,%lx,%lx)\n",
375                 hProcess,(lpProcessAffinityMask?*lpProcessAffinityMask:0),
376                 (lpSystemAffinityMask?*lpSystemAffinityMask:0));
377         /* It is definitely important for a process to know on what processor
378            it is running :-) */
379         if(lpProcessAffinityMask)
380                 *lpProcessAffinityMask=1;
381         if(lpSystemAffinityMask)
382                 *lpSystemAffinityMask=1;
383         return TRUE;
384 }
385
386 /**********************************************************************
387  *           SetThreadAffinityMask
388  * Works now like the Windows95 (no MP support) version
389  */
390 BOOL32 WINAPI SetThreadAffinityMask(HANDLE32 hThread, DWORD dwThreadAffinityMask)
391 {
392         THDB    *thdb = (THDB*)PROCESS_GetObjPtr(hThread,K32OBJ_THREAD);
393
394         if (!thdb) 
395                 return FALSE;
396         if (dwThreadAffinityMask!=1) {
397                 fprintf(stderr,"SetThreadAffinityMask(%d,%ld), only 1 processor supported.\n",(int)hThread,dwThreadAffinityMask);
398                 K32OBJ_DecCount((K32OBJ*)thdb);
399                 return FALSE;
400         }
401         K32OBJ_DecCount((K32OBJ*)thdb);
402         return TRUE;
403 }
404
405 BOOL32 WINAPI CreateProcess32A(
406         LPCSTR appname,LPSTR cmdline,LPSECURITY_ATTRIBUTES processattributes,
407         LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles,
408         DWORD creationflags,LPVOID env,LPCSTR curdir,
409         LPSTARTUPINFO32A startupinfo,LPPROCESS_INFORMATION processinfo
410 ) {
411         fprintf(stderr,"CreateProcess(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p)\n",
412                 appname,cmdline,processattributes,threadattributes,
413                 inherithandles,creationflags,env,curdir,startupinfo,processinfo
414         );
415         /* make from lcc uses system as fallback if CreateProcess returns
416            FALSE, so return false */
417         return FALSE;
418 }
419
420 BOOL32 WINAPI ContinueDebugEvent(DWORD pid,DWORD tid,DWORD contstatus) {
421         fprintf(stderr,"ContinueDebugEvent(%ld,%ld,%ld), stub\n",pid,tid,contstatus);
422         return TRUE;
423 }
424
425 /*********************************************************************
426  *      GetProcessTimes                         [KERNEL32.262]
427  *
428  * FIXME: implement this better ...
429  */
430 BOOL32 WINAPI GetProcessTimes(
431         HANDLE32 hprocess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,
432         LPFILETIME lpKernelTime, LPFILETIME lpUserTime
433 ) {
434         struct tms tms;
435
436         times(&tms);
437         DOSFS_UnixTimeToFileTime(tms.tms_utime,lpUserTime,0);
438         DOSFS_UnixTimeToFileTime(tms.tms_stime,lpKernelTime,0);
439         return TRUE;
440 }
441