Release 970329
[wine/multimedia.git] / win32 / process.c
blob7178bf71bfd20a82c6a2a6bf16f0c5ef39ff7b57
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 "windows.h"
11 #include "winerror.h"
12 #include "heap.h"
13 #include "thread.h"
14 #include "handle32.h"
15 #include "pe_image.h"
16 #include "stddebug.h"
17 #include "debug.h"
19 typedef struct {
20 K32OBJ header;
21 DWORD maxcount;
22 DWORD count;
23 DWORD initial;
24 } K32SEMAPHORE;
26 typedef struct {
27 K32OBJ header;
28 THDB *owning_thread; /* we are locked by this thread */
29 } K32MUTEX;
31 typedef struct {
32 K32OBJ header;
33 } K32EVENT;
35 /***********************************************************************
36 * CreateMutexA (KERNEL32.52)
38 HANDLE32 CreateMutex32A(SECURITY_ATTRIBUTES *sa,BOOL32 on,LPCSTR name)
40 K32MUTEX *mut;
41 HANDLE32 handle;
42 K32OBJ *obj = K32OBJ_FindName( name );
44 if (obj) {
45 if (obj->type == K32OBJ_MUTEX) {
46 SetLastError( ERROR_ALREADY_EXISTS );
47 return PROCESS_AllocHandle( obj,0 );
49 SetLastError( ERROR_DUP_NAME );
50 return 0;
52 mut = (K32MUTEX*)HeapAlloc(GetProcessHeap(),0,sizeof(K32MUTEX));
53 mut->header.type = K32OBJ_MUTEX;
54 mut->header.refcount = 1;
55 mut->owning_thread = NULL;
56 if (name)
57 K32OBJ_AddName(&(mut->header),name);
58 handle = PROCESS_AllocHandle(&(mut->header),0);
59 if (handle != INVALID_HANDLE_VALUE32) {
60 if (on)
61 mut->owning_thread = (THDB *)GetCurrentThreadId();
62 return handle;
64 K32OBJ_DecCount(&(mut->header)); /* also frees name */
65 HeapFree(GetProcessHeap(),0,mut);
66 return 0;
69 /***********************************************************************
70 * CreateMutexW (KERNEL32.53)
72 HANDLE32 CreateMutex32W(SECURITY_ATTRIBUTES *sa, BOOL32 on, LPCWSTR a)
74 LPSTR name = a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL;
75 HANDLE32 ret;
77 ret = CreateMutex32A(sa,on,name);
78 if (name) HeapFree(GetProcessHeap(),0,name);
79 return ret;
82 /***********************************************************************
83 * CreateSemaphoreA (KERNEL32.60)
85 HANDLE32 CreateSemaphore32A(
86 LPSECURITY_ATTRIBUTES sa,LONG initial,LONG max,LPCSTR name
87 ) {
88 K32SEMAPHORE *sem;
89 HANDLE32 handle;
90 K32OBJ *obj = K32OBJ_FindName( name );
92 if (obj) {
93 if (obj->type == K32OBJ_SEMAPHORE) {
94 SetLastError( ERROR_ALREADY_EXISTS );
95 return PROCESS_AllocHandle( obj,0 );
97 SetLastError( ERROR_DUP_NAME );
98 return 0;
100 sem = (K32SEMAPHORE*)HeapAlloc(GetProcessHeap(),0,sizeof(K32SEMAPHORE));
101 sem->header.type = K32OBJ_SEMAPHORE;
102 sem->header.refcount = 1;
104 sem->maxcount = max;
105 sem->count = initial;
106 sem->initial = initial;
107 if (name)
108 K32OBJ_AddName(&(sem->header),name);
109 handle = PROCESS_AllocHandle(&(sem->header),0);
110 if (handle != INVALID_HANDLE_VALUE32)
111 return handle;
112 K32OBJ_DecCount(&(sem->header)); /* also frees name */
113 HeapFree(GetProcessHeap(),0,sem);
114 return 0;
117 /***********************************************************************
118 * CreateSemaphoreW (KERNEL32.61)
120 HANDLE32 CreateSemaphore32W(SECURITY_ATTRIBUTES *sa,LONG initial,LONG max,LPCWSTR a)
122 LPSTR name =a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL;
123 HANDLE32 ret;
125 ret = CreateSemaphore32A(sa,initial,max,name);
126 if (a) HeapFree(GetProcessHeap(),0,name);
127 return ret;
131 /***********************************************************************
132 * OpenSemaphoreA (KERNEL32.403)
134 HANDLE32 OpenSemaphore32A(DWORD desired,BOOL32 inherit,LPCSTR name)
136 K32OBJ *obj = K32OBJ_FindName( name );
138 if (obj) {
139 if (obj->type == K32OBJ_SEMAPHORE)
140 return PROCESS_AllocHandle( obj,0 );
141 SetLastError( ERROR_DUP_NAME );
142 return 0;
144 return 0;
147 /***********************************************************************
148 * OpenSemaphoreA (KERNEL32.404)
150 HANDLE32 OpenSemaphore32W(DWORD desired,BOOL32 inherit,LPCWSTR name)
152 LPSTR nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
153 HANDLE32 ret = OpenSemaphore32A(desired,inherit,nameA);
155 if (name) HeapFree(GetProcessHeap(),0,nameA);
156 return ret;
159 /***********************************************************************
160 * ReleaseSemaphore (KERNEL32.403)
162 BOOL32 ReleaseSemaphore(HANDLE32 hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount) {
163 K32SEMAPHORE *sem;
165 sem = (K32SEMAPHORE*)PROCESS_GetObjPtr(hSemaphore,K32OBJ_SEMAPHORE);
166 if (!sem)
167 return FALSE;
168 if (lpPreviousCount) *lpPreviousCount = sem->count;
169 sem->count += lReleaseCount;
170 if (sem->count>sem->maxcount) {
171 fprintf(stderr,"ReleaseSemaphore(%d,%ld,.), released more then possible??\n",hSemaphore,lReleaseCount);
172 sem->count = sem->maxcount;
175 /* FIXME: wake up all threads blocked on that semaphore */
177 K32OBJ_DecCount(&(sem->header));
178 return TRUE;
181 /***********************************************************************
182 * OpenMutexA (KERNEL32.399)
184 HANDLE32 OpenMutex32A(DWORD desiredaccess, BOOL32 inherithandle, LPCSTR name)
186 K32OBJ *obj = K32OBJ_FindName( name );
188 if (obj) {
189 if (obj->type == K32OBJ_MUTEX)
190 return PROCESS_AllocHandle( obj,0 );
191 SetLastError( ERROR_DUP_NAME );
192 return 0;
194 return 0;
197 /***********************************************************************
198 * OpenMutexW (KERNEL32.400)
200 HANDLE32 OpenMutex32W(DWORD desiredaccess, BOOL32 inherithandle, LPCWSTR name)
202 LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
203 HANDLE32 ret = OpenMutex32A(desiredaccess,inherithandle,nameA);
205 if (name) HeapFree(GetProcessHeap(),0,nameA);
206 return ret;
209 /***********************************************************************
210 * ReleaseMutex (KERNEL32.435)
212 BOOL32 ReleaseMutex (HANDLE32 h)
214 K32MUTEX *mut = (K32MUTEX*)PROCESS_GetObjPtr(h,K32OBJ_MUTEX);
216 if (!mut)
217 return 0;
218 if (mut->owning_thread != (THDB *)GetCurrentThreadId()) {
219 /* set error ... */
220 K32OBJ_DecCount(&(mut->header));
221 return 0;
223 mut->owning_thread = NULL;
225 /* FIXME: wake up all threads blocked on this mutex */
227 K32OBJ_DecCount(&(mut->header));
228 return TRUE;
231 /***********************************************************************
232 * CreateEventA (KERNEL32.43)
234 HANDLE32 CreateEvent32A(SECURITY_ATTRIBUTES *sa,BOOL32 au,BOOL32 on,LPCSTR name)
236 K32EVENT *evt;
237 HANDLE32 handle;
238 K32OBJ *obj = K32OBJ_FindName( name );
240 if (obj) {
241 if (obj->type == K32OBJ_EVENT) {
242 SetLastError( ERROR_ALREADY_EXISTS );
243 return PROCESS_AllocHandle( obj,0 );
245 SetLastError( ERROR_DUP_NAME );
246 return 0;
248 evt = (K32EVENT*)HeapAlloc(GetProcessHeap(),0,sizeof(K32EVENT));
249 evt->header.type = K32OBJ_EVENT;
250 evt->header.refcount = 1;
251 if (name)
252 K32OBJ_AddName(&(evt->header),name);
253 handle = PROCESS_AllocHandle(&(evt->header),0);
254 if (handle != INVALID_HANDLE_VALUE32)
255 return handle;
256 K32OBJ_DecCount(&(evt->header)); /* also frees name */
257 HeapFree(GetProcessHeap(),0,evt);
258 return 0;
261 /***********************************************************************
262 * CreateEventW (KERNEL32.43)
264 HANDLE32 CreateEvent32W(SECURITY_ATTRIBUTES *sa, BOOL32 au, BOOL32 on,LPCWSTR name)
266 LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
267 HANDLE32 ret = CreateEvent32A(sa,au,on,nameA);
269 if (name) HeapFree(GetProcessHeap(),0,nameA);
270 return ret;
273 /***********************************************************************
274 * OpenEventA (KERNEL32.394)
276 HANDLE32 OpenEvent32A(DWORD desiredaccess,BOOL32 inherithandle,LPCSTR name) {
277 K32OBJ *obj = K32OBJ_FindName( name );
279 if (obj) {
280 if (obj->type == K32OBJ_EVENT)
281 return PROCESS_AllocHandle( obj,0 );
282 SetLastError( ERROR_DUP_NAME );
283 return 0;
285 return 0;
288 /***********************************************************************
289 * OpenEventW (KERNEL32.395)
291 HANDLE32 OpenEvent32W(DWORD desiredaccess,BOOL32 inherithandle,LPCWSTR name) {
292 LPSTR nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL;
293 HANDLE32 ret = OpenEvent32A(desiredaccess,inherithandle,nameA);
295 if (name) HeapFree(GetProcessHeap(),0,nameA);
296 return ret;
299 /***********************************************************************
300 * SetEvent (KERNEL32.487)
302 BOOL32 SetEvent (HANDLE32 h)
304 fprintf(stderr,"SetEvent(%d) stub\n",h);
305 return 0;
307 /***********************************************************************
308 * ResetEvent (KERNEL32.439)
310 BOOL32 ResetEvent (HANDLE32 h)
312 fprintf(stderr,"ResetEvent(%d) stub\n",h);
313 return 0;
315 /***********************************************************************
316 * WaitForSingleObject (KERNEL32.561)
318 DWORD WaitForSingleObject(HANDLE32 h, DWORD timeout)
320 fprintf(stderr,"WaitForSingleObject(%d,%ld) stub\n",h,timeout);
321 return 0;
323 /***********************************************************************
324 * DuplicateHandle (KERNEL32.78)
326 BOOL32 DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL32 f, DWORD g)
328 fprintf(stderr,"DuplicateHandle(%d,%d,%d,%p,%ld,%d,%ld) stub\n",a,b,c,d,e,f,g);
329 *d = b;
330 return TRUE;
334 /***********************************************************************
335 * LoadLibraryA (KERNEL32.365)
336 * copied from LoadLibrary
337 * This does not currently support built-in libraries
339 HINSTANCE32 LoadLibrary32A(LPCSTR libname)
341 HINSTANCE32 handle;
342 dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
343 handle = LoadModule16( libname, (LPVOID)-1 );
344 if (handle == (HINSTANCE32) -1)
346 char buffer[256];
347 strcpy( buffer, libname );
348 strcat( buffer, ".dll" );
349 handle = LoadModule16( buffer, (LPVOID)-1 );
351 /* Obtain module handle and call initialization function */
352 #ifndef WINELIB
353 if (handle >= (HINSTANCE32)32) PE_InitializeDLLs( GetExePtr(handle), DLL_PROCESS_ATTACH, NULL);
354 #endif
355 return handle;
358 /***********************************************************************
359 * LoadLibrary32W (KERNEL32.368)
361 HINSTANCE32 LoadLibrary32W(LPCWSTR libnameW)
363 LPSTR libnameA = HEAP_strdupWtoA( GetProcessHeap(), 0, libnameW );
364 HINSTANCE32 ret = LoadLibrary32A( libnameA );
365 HeapFree( GetProcessHeap(), 0, libnameA );
366 return ret;
369 /***********************************************************************
370 * FreeLibrary
372 BOOL32 FreeLibrary32(HINSTANCE32 hLibModule)
374 fprintf(stderr,"FreeLibrary: empty stub\n");
375 return TRUE;
378 /**********************************************************************
379 * GetProcessAffinityMask
381 BOOL32 GetProcessAffinityMask(HANDLE32 hProcess, LPDWORD lpProcessAffinityMask,
382 LPDWORD lpSystemAffinityMask)
384 dprintf_task(stddeb,"GetProcessAffinityMask(%x,%lx,%lx)\n",
385 hProcess,(lpProcessAffinityMask?*lpProcessAffinityMask:0),
386 (lpSystemAffinityMask?*lpSystemAffinityMask:0));
387 /* It is definitely important for a process to know on what processor
388 it is running :-) */
389 if(lpProcessAffinityMask)
390 *lpProcessAffinityMask=1;
391 if(lpSystemAffinityMask)
392 *lpSystemAffinityMask=1;
393 return TRUE;
396 /**********************************************************************
397 * SetThreadAffinityMask
398 * Works now like the Windows95 (no MP support) version
400 BOOL32 SetThreadAffinityMask(HANDLE32 hThread, DWORD dwThreadAffinityMask)
402 THDB *thdb = (THDB*)PROCESS_GetObjPtr(hThread,K32OBJ_THREAD);
404 if (!thdb)
405 return FALSE;
406 if (dwThreadAffinityMask!=1) {
407 fprintf(stderr,"SetThreadAffinityMask(%d,%ld), only 1 processor supported.\n",(int)hThread,dwThreadAffinityMask);
408 K32OBJ_DecCount((K32OBJ*)thdb);
409 return FALSE;
411 K32OBJ_DecCount((K32OBJ*)thdb);
412 return TRUE;
415 BOOL32
416 CreateProcess32A(
417 LPCSTR appname,LPSTR cmdline,LPSECURITY_ATTRIBUTES processattributes,
418 LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles,
419 DWORD creationflags,LPVOID env,LPCSTR curdir,
420 LPSTARTUPINFO32A startupinfo,LPPROCESS_INFORMATION processinfo
422 fprintf(stderr,"CreateProcess(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p)\n",
423 appname,cmdline,processattributes,threadattributes,
424 inherithandles,creationflags,env,curdir,startupinfo,processinfo
426 return TRUE;