4 * Copyright 1996 Alexandre Julliard
21 /* Process self-handle */
22 #define PROCESS_SELF ((HANDLE32)0x7fffffff)
24 static BOOL32
PROCESS_Signaled( K32OBJ
*obj
, DWORD thread_id
);
25 static BOOL32
PROCESS_Satisfied( K32OBJ
*obj
, DWORD thread_id
);
26 static void PROCESS_AddWait( K32OBJ
*obj
, DWORD thread_id
);
27 static void PROCESS_RemoveWait( K32OBJ
*obj
, DWORD thread_id
);
28 static void PROCESS_Destroy( K32OBJ
*obj
);
30 const K32OBJ_OPS PROCESS_Ops
=
32 PROCESS_Signaled
, /* signaled */
33 PROCESS_Satisfied
, /* satisfied */
34 PROCESS_AddWait
, /* add_wait */
35 PROCESS_RemoveWait
, /* remove_wait */
38 PROCESS_Destroy
/* destroy */
42 /***********************************************************************
45 PDB32
*PROCESS_Current(void)
47 return THREAD_Current()->process
;
51 /***********************************************************************
54 * Get a process from a handle, incrementing the PDB refcount.
56 PDB32
*PROCESS_GetPtr( HANDLE32 handle
, DWORD access
)
60 if (handle
== PROCESS_SELF
)
62 pdb
= PROCESS_Current();
63 K32OBJ_IncCount( &pdb
->header
);
66 return (PDB32
*)HANDLE_GetObjPtr( handle
, K32OBJ_PROCESS
, access
);
70 /***********************************************************************
73 * Convert a process id to a PDB, making sure it is valid.
75 PDB32
*PROCESS_IdToPDB( DWORD id
)
79 if (!id
) return PROCESS_Current();
80 pdb
= PROCESS_ID_TO_PDB( id
);
81 if (!K32OBJ_IsValid( &pdb
->header
, K32OBJ_PROCESS
))
83 SetLastError( ERROR_INVALID_PARAMETER
);
90 static int pstr_cmp( const void *ps1
, const void *ps2
)
92 return lstrcmpi32A( *(LPSTR
*)ps1
, *(LPSTR
*)ps2
);
95 /***********************************************************************
98 static BOOL32
PROCESS_FillEnvDB( PDB32
*pdb
, TDB
*pTask
, LPCSTR cmd_line
)
102 LPSTR
*pp
, *array
= NULL
;
104 /* Copy the Win16 environment, sorting it in the process */
106 env
= p
= GlobalLock16( pTask
->pdb
.environment
);
107 for (p
= env
; *p
; p
+= strlen(p
) + 1) count
++;
108 pdb
->env_db
->env_size
= (p
- env
) + 1;
109 pdb
->env_db
->environ
= HeapAlloc( pdb
->heap
, 0, pdb
->env_db
->env_size
);
110 if (!pdb
->env_db
->environ
) goto error
;
111 if (!(array
= HeapAlloc( pdb
->heap
, 0, count
* sizeof(array
[0]) )))
113 for (p
= env
, pp
= array
; *p
; p
+= strlen(p
) + 1) *pp
++ = p
;
114 qsort( array
, count
, sizeof(LPSTR
), pstr_cmp
);
115 p
= pdb
->env_db
->environ
;
116 for (pp
= array
; count
; count
--, pp
++)
122 HeapFree( pdb
->heap
, 0, array
);
125 /* Copy the command line */
126 /* Fixme: Here we rely on the hack that loader/module.c put's the unprocessed
127 commandline after the processed one in Pascal notation.
128 We may access Null data if we get called another way.
129 If we have a real CreateProcess sometimes, the problem to get an unrestricted
130 commandline will go away and we won't need that hack any longer
132 if (!(pdb
->env_db
->cmd_line
=
133 HEAP_strdupA( pdb
->heap
, 0, cmd_line
+ (unsigned char)cmd_line
[0] + 2)))
138 if (pdb
->env_db
->cmd_line
) HeapFree( pdb
->heap
, 0, pdb
->env_db
->cmd_line
);
139 if (array
) HeapFree( pdb
->heap
, 0, array
);
140 if (pdb
->env_db
->environ
) HeapFree( pdb
->heap
, 0, pdb
->env_db
->environ
);
145 /***********************************************************************
148 * Free a PDB and all associated storage.
150 static void PROCESS_FreePDB( PDB32
*pdb
)
152 pdb
->header
.type
= K32OBJ_UNKNOWN
;
153 if (pdb
->heap
&& (pdb
->heap
!= pdb
->system_heap
)) HeapDestroy( pdb
->heap
);
154 if (pdb
->handle_table
) HeapFree( pdb
->system_heap
, 0, pdb
->handle_table
);
155 if (pdb
->load_done_evt
) K32OBJ_DecCount( pdb
->load_done_evt
);
156 if (pdb
->event
) K32OBJ_DecCount( pdb
->event
);
157 DeleteCriticalSection( &pdb
->crit_section
);
158 HeapFree( SystemHeap
, 0, pdb
);
162 /***********************************************************************
165 * Allocate and fill a PDB structure.
167 static PDB32
*PROCESS_CreatePDB( PDB32
*parent
)
169 PDB32
*pdb
= HeapAlloc( SystemHeap
, HEAP_ZERO_MEMORY
, sizeof(PDB32
) );
171 if (!pdb
) return NULL
;
172 pdb
->header
.type
= K32OBJ_PROCESS
;
173 pdb
->header
.refcount
= 1;
174 pdb
->exit_code
= 0x103; /* STILL_ACTIVE */
176 pdb
->running_threads
= 1;
177 pdb
->ring0_threads
= 1;
178 pdb
->system_heap
= SystemHeap
;
179 pdb
->parent
= parent
;
181 pdb
->priority
= 8; /* Normal */
182 pdb
->heap
= pdb
->system_heap
; /* will be changed later on */
184 InitializeCriticalSection( &pdb
->crit_section
);
186 /* Allocate the events */
188 if (!(pdb
->event
= EVENT_Create( TRUE
, FALSE
))) goto error
;
189 if (!(pdb
->load_done_evt
= EVENT_Create( TRUE
, FALSE
))) goto error
;
191 /* Allocate the handle table */
193 if (!(pdb
->handle_table
= HANDLE_AllocTable( pdb
))) goto error
;
197 PROCESS_FreePDB( pdb
);
202 /***********************************************************************
205 BOOL32
PROCESS_Init(void)
207 extern BOOL32
VIRTUAL_Init(void);
208 extern BOOL32 THREAD_InitDone
;
212 /* Initialize virtual memory management */
213 if (!VIRTUAL_Init()) return FALSE
;
215 /* Create the system and SEGPTR heaps */
216 if (!(SystemHeap
= HeapCreate( HEAP_GROWABLE
, 0x10000, 0 ))) return FALSE
;
217 if (!(SegptrHeap
= HeapCreate( HEAP_WINE_SEGPTR
, 0, 0 ))) return FALSE
;
219 /* Create the initial process and thread structures */
220 if (!(pdb
= PROCESS_CreatePDB( NULL
))) return FALSE
;
221 if (!(thdb
= THREAD_Create( pdb
, 0, NULL
, NULL
))) return FALSE
;
222 SET_CUR_THREAD( thdb
);
223 THREAD_InitDone
= TRUE
;
229 /***********************************************************************
232 * Create a new process database and associated info.
234 PDB32
*PROCESS_Create( TDB
*pTask
, LPCSTR cmd_line
)
238 PDB32
*pdb
= PROCESS_CreatePDB( PROCESS_Current() );
240 if (!pdb
) return NULL
;
241 if (!(pModule
= MODULE_GetPtr( pTask
->hModule
))) return 0;
243 /* Create the heap */
245 if (pModule
->module32
)
247 size
= PE_HEADER(pModule
->module32
)->OptionalHeader
.SizeOfHeapReserve
;
248 commit
= PE_HEADER(pModule
->module32
)->OptionalHeader
.SizeOfHeapCommit
;
255 if (!(pdb
->heap
= HeapCreate( HEAP_GROWABLE
, size
, commit
))) goto error
;
256 pdb
->heap_list
= pdb
->heap
;
258 if (!(pdb
->env_db
= HeapAlloc(pdb
->heap
, HEAP_ZERO_MEMORY
, sizeof(ENVDB
))))
260 if (!PROCESS_FillEnvDB( pdb
, pTask
, cmd_line
)) goto error
;
264 PROCESS_FreePDB( pdb
);
269 /***********************************************************************
272 static BOOL32
PROCESS_Signaled( K32OBJ
*obj
, DWORD thread_id
)
274 PDB32
*pdb
= (PDB32
*)obj
;
275 assert( obj
->type
== K32OBJ_PROCESS
);
276 return K32OBJ_OPS( pdb
->event
)->signaled( pdb
->event
, thread_id
);
280 /***********************************************************************
283 * Wait on this object has been satisfied.
285 static BOOL32
PROCESS_Satisfied( K32OBJ
*obj
, DWORD thread_id
)
287 PDB32
*pdb
= (PDB32
*)obj
;
288 assert( obj
->type
== K32OBJ_PROCESS
);
289 return K32OBJ_OPS( pdb
->event
)->satisfied( pdb
->event
, thread_id
);
293 /***********************************************************************
296 * Add thread to object wait queue.
298 static void PROCESS_AddWait( K32OBJ
*obj
, DWORD thread_id
)
300 PDB32
*pdb
= (PDB32
*)obj
;
301 assert( obj
->type
== K32OBJ_PROCESS
);
302 return K32OBJ_OPS( pdb
->event
)->add_wait( pdb
->event
, thread_id
);
306 /***********************************************************************
309 * Remove thread from object wait queue.
311 static void PROCESS_RemoveWait( K32OBJ
*obj
, DWORD thread_id
)
313 PDB32
*pdb
= (PDB32
*)obj
;
314 assert( obj
->type
== K32OBJ_PROCESS
);
315 return K32OBJ_OPS( pdb
->event
)->remove_wait( pdb
->event
, thread_id
);
318 /***********************************************************************
319 * PROCESS_CloseObjHandles
321 * closes all handles that reference "ptr"
322 * note: need to add 1 to the array entry to get to what
323 * CloseHandle expects (there is no zero handle)
325 void PROCESS_CloseObjHandles(PDB32
*pdb
, K32OBJ
*ptr
)
329 assert( pdb
->header
.type
== K32OBJ_PROCESS
);
331 /* Close all handles that have a pointer to ptr */
332 for (handle
= 0; handle
< pdb
->handle_table
->count
; handle
++)
333 if (pdb
->handle_table
->entries
[handle
].ptr
== ptr
)
334 CloseHandle( handle
+1 );
337 /***********************************************************************
339 * note: need to add 1 to the array entry to get to what
340 * CloseHandle expects (there is no zero handle)
342 static void PROCESS_Destroy( K32OBJ
*ptr
)
344 PDB32
*pdb
= (PDB32
*)ptr
;
346 assert( ptr
->type
== K32OBJ_PROCESS
);
348 /* Close all handles */
349 for (handle
= 0; handle
< pdb
->handle_table
->count
; handle
++)
350 if (pdb
->handle_table
->entries
[handle
].ptr
) CloseHandle( handle
+1 );
352 /* Free everything */
354 ptr
->type
= K32OBJ_UNKNOWN
;
355 PROCESS_FreePDB( pdb
);
359 /***********************************************************************
360 * ExitProcess (KERNEL32.100)
362 void WINAPI
ExitProcess( DWORD status
)
364 PDB32
*pdb
= PROCESS_Current();
367 /* FIXME: should kill all running threads of this process */
368 pdb
->exit_code
= status
;
369 EVENT_Set( pdb
->event
);
370 if (pdb
->console
) FreeConsole();
373 __RESTORE_ES
; /* Necessary for Pietrek's showseh example program */
374 TASK_KillCurrentTask( status
);
378 /***********************************************************************
379 * GetCurrentProcess (KERNEL32.198)
381 HANDLE32 WINAPI
GetCurrentProcess(void)
387 /*********************************************************************
388 * OpenProcess (KERNEL32.543)
390 HANDLE32 WINAPI
OpenProcess( DWORD access
, BOOL32 inherit
, DWORD id
)
392 PDB32
*pdb
= PROCESS_ID_TO_PDB(id
);
393 if (!K32OBJ_IsValid( &pdb
->header
, K32OBJ_PROCESS
))
395 SetLastError( ERROR_INVALID_HANDLE
);
398 return HANDLE_Alloc( &pdb
->header
, access
, inherit
);
402 /***********************************************************************
403 * GetCurrentProcessId (KERNEL32.199)
405 DWORD WINAPI
GetCurrentProcessId(void)
407 PDB32
*pdb
= PROCESS_Current();
408 return PDB_TO_PROCESS_ID( pdb
);
412 /***********************************************************************
413 * GetEnvironmentStrings32A (KERNEL32.210) (KERNEL32.211)
415 LPSTR WINAPI
GetEnvironmentStrings32A(void)
417 PDB32
*pdb
= PROCESS_Current();
418 return pdb
->env_db
->environ
;
422 /***********************************************************************
423 * GetEnvironmentStrings32W (KERNEL32.212)
425 LPWSTR WINAPI
GetEnvironmentStrings32W(void)
430 PDB32
*pdb
= PROCESS_Current();
432 size
= HeapSize( GetProcessHeap(), 0, pdb
->env_db
->environ
);
433 if (!(ret
= HeapAlloc( GetProcessHeap(), 0, size
* sizeof(WCHAR
) )))
435 pA
= pdb
->env_db
->environ
;
439 lstrcpyAtoW( pW
, pA
);
449 /***********************************************************************
450 * FreeEnvironmentStrings32A (KERNEL32.141)
452 BOOL32 WINAPI
FreeEnvironmentStrings32A( LPSTR ptr
)
454 PDB32
*pdb
= PROCESS_Current();
455 if (ptr
!= pdb
->env_db
->environ
)
457 SetLastError( ERROR_INVALID_PARAMETER
);
464 /***********************************************************************
465 * FreeEnvironmentStrings32W (KERNEL32.142)
467 BOOL32 WINAPI
FreeEnvironmentStrings32W( LPWSTR ptr
)
469 return HeapFree( GetProcessHeap(), 0, ptr
);
473 /***********************************************************************
474 * GetEnvironmentVariable32A (KERNEL32.213)
476 DWORD WINAPI
GetEnvironmentVariable32A( LPCSTR name
, LPSTR value
, DWORD size
)
481 p
= PROCESS_Current()->env_db
->environ
;
484 SetLastError( ERROR_INVALID_PARAMETER
);
490 res
= lstrncmpi32A( name
, p
, len
);
491 if (res
< 0) goto not_found
;
492 if (!res
&& (p
[len
] == '=')) break;
495 if (!*p
) goto not_found
;
496 if (value
) lstrcpyn32A( value
, p
+ len
+ 1, size
);
498 /* According to the Win32 docs, if there is not enough room, return
499 * the size required to hold the string plus the terminating null
501 if (size
<= len
) len
++;
505 return 0; /* FIXME: SetLastError */
509 /***********************************************************************
510 * GetEnvironmentVariable32W (KERNEL32.214)
512 DWORD WINAPI
GetEnvironmentVariable32W( LPCWSTR nameW
, LPWSTR valW
, DWORD size
)
514 LPSTR name
= HEAP_strdupWtoA( GetProcessHeap(), 0, nameW
);
515 LPSTR val
= HeapAlloc( GetProcessHeap(), 0, size
);
516 DWORD res
= GetEnvironmentVariable32A( name
, val
, size
);
517 HeapFree( GetProcessHeap(), 0, name
);
518 if (valW
) lstrcpynAtoW( valW
, val
, size
);
519 HeapFree( GetProcessHeap(), 0, val
);
524 /***********************************************************************
525 * SetEnvironmentVariable32A (KERNEL32.484)
527 BOOL32 WINAPI
SetEnvironmentVariable32A( LPCSTR name
, LPCSTR value
)
529 INT32 size
, len
, res
;
530 LPSTR p
, env
, new_env
;
531 PDB32
*pdb
= PROCESS_Current();
533 env
= p
= pdb
->env_db
->environ
;
535 /* Find a place to insert the string */
541 res
= lstrncmpi32A( name
, p
, len
);
543 if (!res
&& (p
[len
] == '=')) break;
547 if (!value
&& res
) /* Value to remove doesn't exist already */
550 /* Realloc the buffer */
552 len
= value
? strlen(name
) + strlen(value
) + 2 : 0;
553 if (!res
) len
-= strlen(p
) + 1; /* The name already exists */
554 size
= pdb
->env_db
->env_size
+ len
;
557 LPSTR next
= p
+ strlen(p
) + 1;
558 memmove( next
+ len
, next
, pdb
->env_db
->env_size
- (next
- env
) );
560 if (!(new_env
= HeapReAlloc( GetProcessHeap(), 0, env
, size
)))
562 p
= new_env
+ (p
- env
);
563 if (len
> 0) memmove( p
+ len
, p
, pdb
->env_db
->env_size
- (p
-new_env
) );
565 /* Set the new string */
573 pdb
->env_db
->env_size
= size
;
574 pdb
->env_db
->environ
= new_env
;
579 /***********************************************************************
580 * SetEnvironmentVariable32W (KERNEL32.485)
582 BOOL32 WINAPI
SetEnvironmentVariable32W( LPCWSTR name
, LPCWSTR value
)
584 LPSTR nameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, name
);
585 LPSTR valueA
= HEAP_strdupWtoA( GetProcessHeap(), 0, value
);
586 BOOL32 ret
= SetEnvironmentVariable32A( nameA
, valueA
);
587 HeapFree( GetProcessHeap(), 0, nameA
);
588 HeapFree( GetProcessHeap(), 0, valueA
);
593 /***********************************************************************
594 * ExpandEnvironmentVariablesA (KERNEL32.103)
596 DWORD WINAPI
ExpandEnvironmentStrings32A( LPCSTR src
, LPSTR dst
, DWORD len
)
600 HANDLE32 heap
= GetProcessHeap();
601 LPSTR xdst
= HeapAlloc(heap
,0,10);
605 fprintf(stderr
,"ExpandEnvironmentStrings32A(%s)\n",src
);
608 memset(dst
,'\0',len
);
609 #define CHECK_FREE(n) { \
610 DWORD _needed = (n); \
612 while (cursize-(d-xdst)<_needed) { \
613 DWORD ind = d-xdst; \
616 xdst=(LPSTR)HeapReAlloc(heap,0,xdst,cursize);\
625 end
= s
;do { end
++; } while (*end
&& *end
!='%');
627 LPSTR x
= HeapAlloc(heap
,0,end
-s
+1);
630 lstrcpyn32A(x
,s
+1,end
-s
);
633 /* put expanded variable directly into
634 * destination string, so we don't have
635 * to use temporary buffers.
637 ret
= GetEnvironmentVariable32A(x
,buf
,2);
639 ret
= GetEnvironmentVariable32A(x
,d
,cursize
-(d
-xdst
));
644 CHECK_FREE(strlen(x
)+2);
661 ret
= lstrlen32A(xdst
)+1;
663 lstrcpy32A(dst
,xdst
);
664 HeapFree(heap
,0,xdst
);
668 /***********************************************************************
669 * ExpandEnvironmentVariablesA (KERNEL32.104)
671 DWORD WINAPI
ExpandEnvironmentStrings32W( LPCWSTR src
, LPWSTR dst
, DWORD len
)
673 HANDLE32 heap
= GetProcessHeap();
674 LPSTR srcA
= HEAP_strdupWtoA(heap
,0,src
);
675 LPSTR dstA
= HeapAlloc(heap
,0,len
);
676 DWORD ret
= ExpandEnvironmentStrings32A(srcA
,dstA
,len
);
678 lstrcpyAtoW(dst
,dstA
);
679 HeapFree(heap
,0,dstA
);
680 HeapFree(heap
,0,srcA
);
684 /***********************************************************************
685 * GetProcessHeap (KERNEL32.259)
687 HANDLE32 WINAPI
GetProcessHeap(void)
689 PDB32
*pdb
= PROCESS_Current();
690 return pdb
->heap
? pdb
->heap
: SystemHeap
;
694 /***********************************************************************
695 * GetThreadLocale (KERNEL32.295)
697 LCID WINAPI
GetThreadLocale(void)
699 return PROCESS_Current()->locale
;
703 /***********************************************************************
704 * SetPriorityClass (KERNEL32.503)
706 BOOL32 WINAPI
SetPriorityClass( HANDLE32 hprocess
, DWORD priorityclass
)
708 PDB32
*pdb
= PROCESS_GetPtr( hprocess
, PROCESS_SET_INFORMATION
);
709 if (!pdb
) return FALSE
;
710 switch (priorityclass
)
712 case NORMAL_PRIORITY_CLASS
:
713 pdb
->priority
= 0x00000008;
715 case IDLE_PRIORITY_CLASS
:
716 pdb
->priority
= 0x00000004;
718 case HIGH_PRIORITY_CLASS
:
719 pdb
->priority
= 0x0000000d;
721 case REALTIME_PRIORITY_CLASS
:
722 pdb
->priority
= 0x00000018;
725 fprintf(stderr
,"SetPriorityClass: unknown priority class %ld\n",priorityclass
);
728 K32OBJ_DecCount( &pdb
->header
);
733 /***********************************************************************
734 * GetPriorityClass (KERNEL32.250)
736 DWORD WINAPI
GetPriorityClass(HANDLE32 hprocess
)
738 PDB32
*pdb
= PROCESS_GetPtr( hprocess
, PROCESS_QUERY_INFORMATION
);
742 switch (pdb
->priority
)
745 ret
= NORMAL_PRIORITY_CLASS
;
748 ret
= IDLE_PRIORITY_CLASS
;
751 ret
= HIGH_PRIORITY_CLASS
;
754 ret
= REALTIME_PRIORITY_CLASS
;
757 fprintf(stderr
,"GetPriorityClass: unknown priority %ld\n",pdb
->priority
);
759 K32OBJ_DecCount( &pdb
->header
);
765 /***********************************************************************
766 * GetStdHandle (KERNEL32.276)
768 * FIXME: These should be allocated when a console is created, or inherited
771 HANDLE32 WINAPI
GetStdHandle( DWORD std_handle
)
775 PDB32
*pdb
= PROCESS_Current();
779 case STD_INPUT_HANDLE
:
780 if (pdb
->env_db
->hStdin
) return pdb
->env_db
->hStdin
;
783 case STD_OUTPUT_HANDLE
:
784 if (pdb
->env_db
->hStdout
) return pdb
->env_db
->hStdout
;
787 case STD_ERROR_HANDLE
:
788 if (pdb
->env_db
->hStderr
) return pdb
->env_db
->hStderr
;
792 SetLastError( ERROR_INVALID_PARAMETER
);
793 return INVALID_HANDLE_VALUE32
;
795 hFile
= FILE_DupUnixHandle( fd
);
796 if (hFile
!= HFILE_ERROR32
)
798 FILE_SetFileType( hFile
, FILE_TYPE_CHAR
);
801 case STD_INPUT_HANDLE
: pdb
->env_db
->hStdin
= hFile
; break;
802 case STD_OUTPUT_HANDLE
: pdb
->env_db
->hStdout
= hFile
; break;
803 case STD_ERROR_HANDLE
: pdb
->env_db
->hStderr
= hFile
; break;
810 /***********************************************************************
811 * SetStdHandle (KERNEL32.506)
813 BOOL32 WINAPI
SetStdHandle( DWORD std_handle
, HANDLE32 handle
)
815 PDB32
*pdb
= PROCESS_Current();
816 /* FIXME: should we close the previous handle? */
819 case STD_INPUT_HANDLE
:
820 pdb
->env_db
->hStdin
= handle
;
822 case STD_OUTPUT_HANDLE
:
823 pdb
->env_db
->hStdout
= handle
;
825 case STD_ERROR_HANDLE
:
826 pdb
->env_db
->hStderr
= handle
;
829 SetLastError( ERROR_INVALID_PARAMETER
);
833 /***********************************************************************
834 * GetProcessVersion (KERNEL32)
836 DWORD WINAPI
GetProcessVersion( DWORD processid
)
839 PDB32
*pdb
= PROCESS_IdToPDB( processid
);
842 if (!(pTask
= (TDB
*)GlobalLock16( pdb
->task
))) return 0;
843 return (pTask
->version
&0xff) | (((pTask
->version
>>8) & 0xff)<<16);
846 /***********************************************************************
847 * GetProcessFlags (KERNEL32)
849 DWORD WINAPI
GetProcessFlags( DWORD processid
)
851 PDB32
*pdb
= PROCESS_IdToPDB( processid
);
856 /***********************************************************************
857 * SetProcessWorkingSetSize (KERNEL32)
859 BOOL32 WINAPI
SetProcessWorkingSetSize(HANDLE32 hProcess
,DWORD minset
,
862 fprintf(stderr
,"SetProcessWorkingSetSize(0x%08x,%ld,%ld), STUB!\n",
863 hProcess
,minset
,maxset
868 /***********************************************************************
869 * GetProcessWorkingSetSize (KERNEL32)
871 BOOL32 WINAPI
GetProcessWorkingSetSize(HANDLE32 hProcess
,LPDWORD minset
,
874 fprintf(stderr
,"SetProcessWorkingSetSize(0x%08x,%p,%p), STUB!\n",
875 hProcess
,minset
,maxset
877 /* 32 MB working set size */
878 if (minset
) *minset
= 32*1024*1024;
879 if (maxset
) *maxset
= 32*1024*1024;
883 /***********************************************************************
884 * SetProcessShutdownParameters (KERNEL32)
886 BOOL32 WINAPI
SetProcessShutdownParameters(DWORD level
,DWORD flags
)
888 fprintf(stderr
,"SetProcessShutdownParameters(%ld,0x%08lx), STUB!\n",
894 /***********************************************************************
895 * ReadProcessMemory (KERNEL32)
896 * FIXME: check this, if we ever run win32 binaries in different addressspaces
897 * ... and add a sizecheck
899 BOOL32 WINAPI
ReadProcessMemory( HANDLE32 hProcess
, LPCVOID lpBaseAddress
,
900 LPVOID lpBuffer
, DWORD nSize
,
901 LPDWORD lpNumberOfBytesRead
)
903 memcpy(lpBuffer
,lpBaseAddress
,nSize
);
904 if (lpNumberOfBytesRead
) *lpNumberOfBytesRead
= nSize
;
908 /***********************************************************************
909 * WriteProcessMemory (KERNEL32)
910 * FIXME: check this, if we ever run win32 binaries in different addressspaces
911 * ... and add a sizecheck
913 BOOL32 WINAPI
WriteProcessMemory(HANDLE32 hProcess
, LPCVOID lpBaseAddress
,
914 LPVOID lpBuffer
, DWORD nSize
,
915 LPDWORD lpNumberOfBytesWritten
)
917 memcpy(lpBaseAddress
,lpBuffer
,nSize
);
918 if (lpNumberOfBytesWritten
) *lpNumberOfBytesWritten
= nSize
;
922 /***********************************************************************
923 * ConvertToGlobalHandle (KERNEL32)
924 * FIXME: this is not correctly implemented...
926 HANDLE32 WINAPI
ConvertToGlobalHandle(HANDLE32 h
)
928 fprintf(stderr
,"ConvertToGlobalHandle(%d),stub!\n",h
);
932 /***********************************************************************
933 * RegisterServiceProcess (KERNEL32)
935 * A service process calls this function to ensure that it continues to run
936 * even after a user logged off.
938 DWORD
RegisterServiceProcess(DWORD dwProcessId
, DWORD dwType
)
940 /* I don't think that Wine needs to do anything in that function */
941 return 1; /* success */