Release 970509
[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 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 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 CreateSemaphore32A(
88         LPSECURITY_ATTRIBUTES sa,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 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 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 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 ReleaseSemaphore(HANDLE32 hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount) {
165         K32SEMAPHORE    *sem;
166
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;
175         }
176
177         /* FIXME: wake up all threads blocked on that semaphore */
178
179         K32OBJ_DecCount(&(sem->header));
180         return TRUE;
181 }
182
183 /***********************************************************************
184  *           OpenMutexA    (KERNEL32.399)
185  */
186 HANDLE32 OpenMutex32A(DWORD desiredaccess, BOOL32 inherithandle, LPCSTR name)
187 {
188         K32OBJ          *obj = K32OBJ_FindName( name );
189
190         if (obj) {
191                 if (obj->type == K32OBJ_MUTEX)
192                         return PROCESS_AllocHandle( obj,0 );
193                 SetLastError( ERROR_DUP_NAME );
194                 return 0;
195         }
196         return 0;
197 }
198
199 /***********************************************************************
200  *           OpenMutexW    (KERNEL32.400)
201  */
202 HANDLE32 OpenMutex32W(DWORD desiredaccess, BOOL32 inherithandle, LPCWSTR name)
203 {
204         LPSTR           nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
205         HANDLE32        ret = OpenMutex32A(desiredaccess,inherithandle,nameA);
206
207         if (name) HeapFree(GetProcessHeap(),0,nameA);
208         return ret;
209 }
210
211 /***********************************************************************
212  *           ReleaseMutex    (KERNEL32.435)
213  */
214 BOOL32 ReleaseMutex (HANDLE32 h)
215 {
216         K32MUTEX        *mut = (K32MUTEX*)PROCESS_GetObjPtr(h,K32OBJ_MUTEX);
217
218         if (!mut)
219                 return 0;
220         if (mut->owning_thread != (THDB *)GetCurrentThreadId()) {
221                 /* set error ... */
222                 K32OBJ_DecCount(&(mut->header));
223                 return 0;
224         }
225         mut->owning_thread = NULL;
226
227         /* FIXME: wake up all threads blocked on this mutex */
228
229         K32OBJ_DecCount(&(mut->header));
230         return TRUE;
231 }
232
233 /***********************************************************************
234  *           CreateEventA    (KERNEL32.43)
235  */
236 HANDLE32 CreateEvent32A(SECURITY_ATTRIBUTES *sa,BOOL32 au,BOOL32 on,LPCSTR name)
237 {
238         K32EVENT        *evt;
239         HANDLE32        handle;
240         K32OBJ          *obj = K32OBJ_FindName( name );
241
242         if (obj) {
243                 if (obj->type == K32OBJ_EVENT) {
244                         SetLastError( ERROR_ALREADY_EXISTS );
245                         return PROCESS_AllocHandle( obj,0 );
246                 }
247                 SetLastError( ERROR_DUP_NAME );
248                 return 0;
249         }
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;
261 }
262
263 /***********************************************************************
264  *           CreateEventW    (KERNEL32.43)
265  */
266 HANDLE32 CreateEvent32W(SECURITY_ATTRIBUTES *sa, BOOL32 au, BOOL32 on,LPCWSTR name)
267 {
268         LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
269         HANDLE32 ret = CreateEvent32A(sa,au,on,nameA);
270
271         if (name) HeapFree(GetProcessHeap(),0,nameA);
272         return ret;
273 }
274
275 /***********************************************************************
276  *           OpenEventA    (KERNEL32.394)
277  */
278 HANDLE32 OpenEvent32A(DWORD desiredaccess,BOOL32 inherithandle,LPCSTR name) {
279         K32OBJ          *obj = K32OBJ_FindName( name );
280
281         if (obj) {
282                 if (obj->type == K32OBJ_EVENT)
283                         return PROCESS_AllocHandle( obj,0 );
284                 SetLastError( ERROR_DUP_NAME );
285                 return 0;
286         }
287         return 0;
288 }
289
290 /***********************************************************************
291  *           OpenEventW    (KERNEL32.395)
292  */
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);
296
297         if (name) HeapFree(GetProcessHeap(),0,nameA);
298         return ret;
299 }
300
301 /***********************************************************************
302  *           SetEvent    (KERNEL32.487)
303  */
304 BOOL32 SetEvent (HANDLE32 h)
305 {
306         fprintf(stderr,"SetEvent(%d) stub\n",h);
307         return 0;
308 }
309 /***********************************************************************
310  *           ResetEvent    (KERNEL32.439)
311  */
312 BOOL32 ResetEvent (HANDLE32 h)
313 {
314         fprintf(stderr,"ResetEvent(%d) stub\n",h);
315         return 0;
316 }
317
318 /***********************************************************************
319  *           WaitForSingleObject    (KERNEL32.561)
320  */
321 DWORD WaitForSingleObject(HANDLE32 h, DWORD timeout)
322 {
323         fprintf(stderr,"WaitForSingleObject(%d,%ld) stub\n",h,timeout);
324         return 0;
325 }
326
327 /***********************************************************************
328  *           WaitForSingleObject    (USER32.399)
329  */
330 DWORD MsgWaitForMultipleObjects(
331         DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds,
332         DWORD dwWakeMask
333 ) {
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;
340 }
341 /***********************************************************************
342  *           DuplicateHandle    (KERNEL32.78)
343  */
344 BOOL32 DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL32 f, DWORD g)
345 {
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;
349 }
350
351
352 /***********************************************************************
353  *           LoadLibraryA         (KERNEL32.365)
354  * copied from LoadLibrary
355  * This does not currently support built-in libraries
356  */
357 HINSTANCE32 LoadLibrary32A(LPCSTR libname)
358 {
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)
363         {
364                 char buffer[256];
365                 strcpy( buffer, libname );
366                 strcat( buffer, ".dll" );
367                 handle = LoadModule16( buffer, (LPVOID)-1 );
368         }
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;
374 }
375
376 /***********************************************************************
377  *           LoadLibrary32W         (KERNEL32.368)
378  */
379 HINSTANCE32 LoadLibrary32W(LPCWSTR libnameW)
380 {
381     LPSTR libnameA = HEAP_strdupWtoA( GetProcessHeap(), 0, libnameW );
382     HINSTANCE32 ret = LoadLibrary32A( libnameA );
383     HeapFree( GetProcessHeap(), 0, libnameA );
384     return ret;
385 }
386
387 /***********************************************************************
388  *           FreeLibrary
389  */
390 BOOL32 FreeLibrary32(HINSTANCE32 hLibModule)
391 {
392         fprintf(stderr,"FreeLibrary: empty stub\n");
393         return TRUE;
394 }
395
396 /**********************************************************************
397  *          GetProcessAffinityMask
398  */
399 BOOL32 GetProcessAffinityMask(HANDLE32 hProcess, LPDWORD lpProcessAffinityMask,
400   LPDWORD lpSystemAffinityMask)
401 {
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;
412 }
413
414 /**********************************************************************
415  *           SetThreadAffinityMask
416  * Works now like the Windows95 (no MP support) version
417  */
418 BOOL32 SetThreadAffinityMask(HANDLE32 hThread, DWORD dwThreadAffinityMask)
419 {
420         THDB    *thdb = (THDB*)PROCESS_GetObjPtr(hThread,K32OBJ_THREAD);
421
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;
428         }
429         K32OBJ_DecCount((K32OBJ*)thdb);
430         return TRUE;
431 }
432
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
439 ) {
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
443         );
444         return TRUE;
445 }
446
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;
451 }
452
453 /*********************************************************************
454  *      GetProcessTimes                         [KERNEL32.262]
455  *
456  * FIXME: implement this better ...
457  */
458 BOOL32
459 GetProcessTimes(
460         HANDLE32 hprocess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,
461         LPFILETIME lpKernelTime, LPFILETIME lpUserTime
462 ) {
463         struct tms tms;
464
465         times(&tms);
466         DOSFS_UnixTimeToFileTime(tms.tms_utime,lpUserTime,0);
467         DOSFS_UnixTimeToFileTime(tms.tms_stime,lpKernelTime,0);
468         return TRUE;
469 }
470