makefiles: Don't use standard libs for programs that specify -nodefaultlibs.
[wine/zf.git] / dlls / kernel32 / process.c
blob5146622230dc54f8ca24216f1552954038a5e165
1 /*
2 * Win32 processes
4 * Copyright 1996, 1998 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include <assert.h>
25 #include <ctype.h>
26 #include <errno.h>
27 #include <signal.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <time.h>
31 #ifdef HAVE_SYS_TIME_H
32 # include <sys/time.h>
33 #endif
34 #ifdef HAVE_SYS_IOCTL_H
35 #include <sys/ioctl.h>
36 #endif
37 #ifdef HAVE_SYS_SOCKET_H
38 #include <sys/socket.h>
39 #endif
40 #include <sys/types.h>
41 #ifdef HAVE_SYS_WAIT_H
42 # include <sys/wait.h>
43 #endif
44 #ifdef HAVE_UNISTD_H
45 # include <unistd.h>
46 #endif
48 #include "ntstatus.h"
49 #define WIN32_NO_STATUS
50 #include "winternl.h"
51 #include "winbase.h"
52 #include "wincon.h"
53 #include "kernel_private.h"
54 #include "psapi.h"
55 #include "wine/exception.h"
56 #include "wine/library.h"
57 #include "wine/server.h"
58 #include "wine/unicode.h"
59 #include "wine/asm.h"
60 #include "wine/debug.h"
62 WINE_DEFAULT_DEBUG_CHANNEL(process);
63 WINE_DECLARE_DEBUG_CHANNEL(relay);
65 typedef struct
67 LPSTR lpEnvAddress;
68 LPSTR lpCmdLine;
69 LPSTR lpCmdShow;
70 DWORD dwReserved;
71 } LOADPARMS32;
73 HMODULE kernel32_handle = 0;
74 SYSTEM_BASIC_INFORMATION system_info = { 0 };
76 const WCHAR DIR_Windows[] = {'C',':','\\','w','i','n','d','o','w','s',0};
77 const WCHAR DIR_System[] = {'C',':','\\','w','i','n','d','o','w','s',
78 '\\','s','y','s','t','e','m','3','2',0};
80 /* Process flags */
81 #define PDB32_DEBUGGED 0x0001 /* Process is being debugged */
82 #define PDB32_WIN16_PROC 0x0008 /* Win16 process */
83 #define PDB32_DOS_PROC 0x0010 /* Dos process */
84 #define PDB32_CONSOLE_PROC 0x0020 /* Console process */
85 #define PDB32_FILE_APIS_OEM 0x0040 /* File APIs are OEM */
86 #define PDB32_WIN32S_PROC 0x8000 /* Win32s process */
89 #ifdef __i386__
90 extern DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry );
91 __ASM_GLOBAL_FUNC( call_process_entry,
92 "pushl %ebp\n\t"
93 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
94 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
95 "movl %esp,%ebp\n\t"
96 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
97 "pushl 4(%ebp)\n\t" /* deliberately mis-align the stack by 8, Doom 3 needs this */
98 "pushl 4(%ebp)\n\t" /* Driller expects readable address at this offset */
99 "pushl 4(%ebp)\n\t"
100 "pushl 8(%ebp)\n\t"
101 "call *12(%ebp)\n\t"
102 "leave\n\t"
103 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
104 __ASM_CFI(".cfi_same_value %ebp\n\t")
105 "ret" )
107 __ASM_GLOBAL_FUNC( __wine_start_process,
108 "pushl %ebp\n\t"
109 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
110 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
111 "movl %esp,%ebp\n\t"
112 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
113 "pushl %ebx\n\t" /* arg */
114 "pushl %eax\n\t" /* entry */
115 "call " __ASM_NAME("start_process") )
116 #else
117 static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry )
119 return entry( peb );
121 #endif
123 /***********************************************************************
124 * __wine_start_process
126 * Startup routine of a new process. Runs on the new process stack.
128 #ifdef __i386__
129 void CDECL start_process( LPTHREAD_START_ROUTINE entry, PEB *peb )
130 #else
131 void CDECL __wine_start_process( LPTHREAD_START_ROUTINE entry, PEB *peb )
132 #endif
134 BOOL being_debugged;
136 if (!entry)
138 ERR( "%s doesn't have an entry point, it cannot be executed\n",
139 debugstr_w(peb->ProcessParameters->ImagePathName.Buffer) );
140 ExitThread( 1 );
143 TRACE_(relay)( "\1Starting process %s (entryproc=%p)\n",
144 debugstr_w(peb->ProcessParameters->ImagePathName.Buffer), entry );
146 __TRY
148 if (!CheckRemoteDebuggerPresent( GetCurrentProcess(), &being_debugged ))
149 being_debugged = FALSE;
151 SetLastError( 0 ); /* clear error code */
152 if (being_debugged) DbgBreakPoint();
153 ExitThread( call_process_entry( peb, entry ));
155 __EXCEPT(UnhandledExceptionFilter)
157 TerminateProcess( GetCurrentProcess(), GetExceptionCode() );
159 __ENDTRY
160 abort(); /* should not be reached */
164 /***********************************************************************
165 * wait_input_idle
167 * Wrapper to call WaitForInputIdle USER function
169 typedef DWORD (WINAPI *WaitForInputIdle_ptr)( HANDLE hProcess, DWORD dwTimeOut );
171 static DWORD wait_input_idle( HANDLE process, DWORD timeout )
173 HMODULE mod = GetModuleHandleA( "user32.dll" );
174 if (mod)
176 WaitForInputIdle_ptr ptr = (WaitForInputIdle_ptr)GetProcAddress( mod, "WaitForInputIdle" );
177 if (ptr) return ptr( process, timeout );
179 return 0;
183 /***********************************************************************
184 * WinExec (KERNEL32.@)
186 UINT WINAPI DECLSPEC_HOTPATCH WinExec( LPCSTR lpCmdLine, UINT nCmdShow )
188 PROCESS_INFORMATION info;
189 STARTUPINFOA startup;
190 char *cmdline;
191 UINT ret;
193 memset( &startup, 0, sizeof(startup) );
194 startup.cb = sizeof(startup);
195 startup.dwFlags = STARTF_USESHOWWINDOW;
196 startup.wShowWindow = nCmdShow;
198 /* cmdline needs to be writable for CreateProcess */
199 if (!(cmdline = HeapAlloc( GetProcessHeap(), 0, strlen(lpCmdLine)+1 ))) return 0;
200 strcpy( cmdline, lpCmdLine );
202 if (CreateProcessA( NULL, cmdline, NULL, NULL, FALSE,
203 0, NULL, NULL, &startup, &info ))
205 /* Give 30 seconds to the app to come up */
206 if (wait_input_idle( info.hProcess, 30000 ) == WAIT_FAILED)
207 WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
208 ret = 33;
209 /* Close off the handles */
210 CloseHandle( info.hThread );
211 CloseHandle( info.hProcess );
213 else if ((ret = GetLastError()) >= 32)
215 FIXME("Strange error set by CreateProcess: %d\n", ret );
216 ret = 11;
218 HeapFree( GetProcessHeap(), 0, cmdline );
219 return ret;
223 /**********************************************************************
224 * LoadModule (KERNEL32.@)
226 DWORD WINAPI LoadModule( LPCSTR name, LPVOID paramBlock )
228 LOADPARMS32 *params = paramBlock;
229 PROCESS_INFORMATION info;
230 STARTUPINFOA startup;
231 DWORD ret;
232 LPSTR cmdline, p;
233 char filename[MAX_PATH];
234 BYTE len;
236 if (!name) return ERROR_FILE_NOT_FOUND;
238 if (!SearchPathA( NULL, name, ".exe", sizeof(filename), filename, NULL ) &&
239 !SearchPathA( NULL, name, NULL, sizeof(filename), filename, NULL ))
240 return GetLastError();
242 len = (BYTE)params->lpCmdLine[0];
243 if (!(cmdline = HeapAlloc( GetProcessHeap(), 0, strlen(filename) + len + 2 )))
244 return ERROR_NOT_ENOUGH_MEMORY;
246 strcpy( cmdline, filename );
247 p = cmdline + strlen(cmdline);
248 *p++ = ' ';
249 memcpy( p, params->lpCmdLine + 1, len );
250 p[len] = 0;
252 memset( &startup, 0, sizeof(startup) );
253 startup.cb = sizeof(startup);
254 if (params->lpCmdShow)
256 startup.dwFlags = STARTF_USESHOWWINDOW;
257 startup.wShowWindow = ((WORD *)params->lpCmdShow)[1];
260 if (CreateProcessA( filename, cmdline, NULL, NULL, FALSE, 0,
261 params->lpEnvAddress, NULL, &startup, &info ))
263 /* Give 30 seconds to the app to come up */
264 if (wait_input_idle( info.hProcess, 30000 ) == WAIT_FAILED)
265 WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
266 ret = 33;
267 /* Close off the handles */
268 CloseHandle( info.hThread );
269 CloseHandle( info.hProcess );
271 else if ((ret = GetLastError()) >= 32)
273 FIXME("Strange error set by CreateProcess: %u\n", ret );
274 ret = 11;
277 HeapFree( GetProcessHeap(), 0, cmdline );
278 return ret;
282 /***********************************************************************
283 * ExitProcess (KERNEL32.@)
285 * Exits the current process.
287 * PARAMS
288 * status [I] Status code to exit with.
290 * RETURNS
291 * Nothing.
293 #ifdef __i386__
294 __ASM_STDCALL_FUNC( ExitProcess, 4, /* Shrinker depend on this particular ExitProcess implementation */
295 "pushl %ebp\n\t"
296 ".byte 0x8B, 0xEC\n\t" /* movl %esp, %ebp */
297 ".byte 0x6A, 0x00\n\t" /* pushl $0 */
298 ".byte 0x68, 0x00, 0x00, 0x00, 0x00\n\t" /* pushl $0 - 4 bytes immediate */
299 "pushl 8(%ebp)\n\t"
300 "call " __ASM_STDCALL("RtlExitUserProcess",4) "\n\t"
301 "leave\n\t"
302 "ret $4" )
303 #else
305 void WINAPI ExitProcess( DWORD status )
307 RtlExitUserProcess( status );
310 #endif
312 /***********************************************************************
313 * GetExitCodeProcess [KERNEL32.@]
315 * Gets termination status of specified process.
317 * PARAMS
318 * hProcess [in] Handle to the process.
319 * lpExitCode [out] Address to receive termination status.
321 * RETURNS
322 * Success: TRUE
323 * Failure: FALSE
325 BOOL WINAPI GetExitCodeProcess( HANDLE hProcess, LPDWORD lpExitCode )
327 PROCESS_BASIC_INFORMATION pbi;
329 if (!set_ntstatus( NtQueryInformationProcess( hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL )))
330 return FALSE;
331 if (lpExitCode) *lpExitCode = pbi.ExitStatus;
332 return TRUE;
336 /**************************************************************************
337 * FatalExit (KERNEL32.@)
339 void WINAPI FatalExit( int code )
341 WARN( "FatalExit\n" );
342 ExitProcess( code );
346 /***********************************************************************
347 * GetProcessFlags (KERNEL32.@)
349 DWORD WINAPI GetProcessFlags( DWORD processid )
351 IMAGE_NT_HEADERS *nt;
352 DWORD flags = 0;
354 if (processid && processid != GetCurrentProcessId()) return 0;
356 if ((nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress )))
358 if (nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
359 flags |= PDB32_CONSOLE_PROC;
361 if (!AreFileApisANSI()) flags |= PDB32_FILE_APIS_OEM;
362 if (IsDebuggerPresent()) flags |= PDB32_DEBUGGED;
363 return flags;
367 /***********************************************************************
368 * ConvertToGlobalHandle (KERNEL32.@)
370 HANDLE WINAPI ConvertToGlobalHandle(HANDLE hSrc)
372 HANDLE ret = INVALID_HANDLE_VALUE;
373 DuplicateHandle( GetCurrentProcess(), hSrc, GetCurrentProcess(), &ret, 0, FALSE,
374 DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS | DUP_HANDLE_CLOSE_SOURCE );
375 return ret;
379 /***********************************************************************
380 * SetHandleContext (KERNEL32.@)
382 BOOL WINAPI SetHandleContext(HANDLE hnd,DWORD context)
384 FIXME("(%p,%d), stub. In case this got called by WSOCK32/WS2_32: "
385 "the external WINSOCK DLLs won't work with WINE, don't use them.\n",hnd,context);
386 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
387 return FALSE;
391 /***********************************************************************
392 * GetHandleContext (KERNEL32.@)
394 DWORD WINAPI GetHandleContext(HANDLE hnd)
396 FIXME("(%p), stub. In case this got called by WSOCK32/WS2_32: "
397 "the external WINSOCK DLLs won't work with WINE, don't use them.\n",hnd);
398 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
399 return 0;
403 /***********************************************************************
404 * CreateSocketHandle (KERNEL32.@)
406 HANDLE WINAPI CreateSocketHandle(void)
408 FIXME("(), stub. In case this got called by WSOCK32/WS2_32: "
409 "the external WINSOCK DLLs won't work with WINE, don't use them.\n");
410 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
411 return INVALID_HANDLE_VALUE;
415 /***********************************************************************
416 * SetProcessAffinityMask (KERNEL32.@)
418 BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD_PTR affmask )
420 return set_ntstatus( NtSetInformationProcess( hProcess, ProcessAffinityMask,
421 &affmask, sizeof(DWORD_PTR) ));
425 /**********************************************************************
426 * GetProcessAffinityMask (KERNEL32.@)
428 BOOL WINAPI GetProcessAffinityMask( HANDLE hProcess, PDWORD_PTR process_mask, PDWORD_PTR system_mask )
430 if (process_mask)
432 if (!set_ntstatus( NtQueryInformationProcess( hProcess, ProcessAffinityMask,
433 process_mask, sizeof(*process_mask), NULL )))
434 return FALSE;
436 if (system_mask)
438 SYSTEM_BASIC_INFORMATION info;
440 if (!set_ntstatus( NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )))
441 return FALSE;
442 *system_mask = info.ActiveProcessorsAffinityMask;
444 return TRUE;
448 /***********************************************************************
449 * GetProcessVersion (KERNEL32.@)
451 DWORD WINAPI GetProcessVersion( DWORD pid )
453 HANDLE process;
454 NTSTATUS status;
455 PROCESS_BASIC_INFORMATION pbi;
456 SIZE_T count;
457 PEB peb;
458 IMAGE_DOS_HEADER dos;
459 IMAGE_NT_HEADERS nt;
460 DWORD ver = 0;
462 if (!pid || pid == GetCurrentProcessId())
464 IMAGE_NT_HEADERS *pnt;
466 if ((pnt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress )))
467 return ((pnt->OptionalHeader.MajorSubsystemVersion << 16) |
468 pnt->OptionalHeader.MinorSubsystemVersion);
469 return 0;
472 process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pid);
473 if (!process) return 0;
475 status = NtQueryInformationProcess(process, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
476 if (status) goto err;
478 status = NtReadVirtualMemory(process, pbi.PebBaseAddress, &peb, sizeof(peb), &count);
479 if (status || count != sizeof(peb)) goto err;
481 memset(&dos, 0, sizeof(dos));
482 status = NtReadVirtualMemory(process, peb.ImageBaseAddress, &dos, sizeof(dos), &count);
483 if (status || count != sizeof(dos)) goto err;
484 if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto err;
486 memset(&nt, 0, sizeof(nt));
487 status = NtReadVirtualMemory(process, (char *)peb.ImageBaseAddress + dos.e_lfanew, &nt, sizeof(nt), &count);
488 if (status || count != sizeof(nt)) goto err;
489 if (nt.Signature != IMAGE_NT_SIGNATURE) goto err;
491 ver = MAKELONG(nt.OptionalHeader.MinorSubsystemVersion, nt.OptionalHeader.MajorSubsystemVersion);
493 err:
494 CloseHandle(process);
496 if (status != STATUS_SUCCESS)
497 SetLastError(RtlNtStatusToDosError(status));
499 return ver;
503 /***********************************************************************
504 * SetProcessWorkingSetSize [KERNEL32.@]
505 * Sets the min/max working set sizes for a specified process.
507 * PARAMS
508 * process [I] Handle to the process of interest
509 * minset [I] Specifies minimum working set size
510 * maxset [I] Specifies maximum working set size
512 * RETURNS
513 * Success: TRUE
514 * Failure: FALSE
516 BOOL WINAPI SetProcessWorkingSetSize(HANDLE process, SIZE_T minset, SIZE_T maxset)
518 return SetProcessWorkingSetSizeEx(process, minset, maxset, 0);
521 /***********************************************************************
522 * K32EmptyWorkingSet (KERNEL32.@)
524 BOOL WINAPI K32EmptyWorkingSet(HANDLE hProcess)
526 return SetProcessWorkingSetSize(hProcess, (SIZE_T)-1, (SIZE_T)-1);
530 /***********************************************************************
531 * GetProcessWorkingSetSize (KERNEL32.@)
533 BOOL WINAPI GetProcessWorkingSetSize(HANDLE process, SIZE_T *minset, SIZE_T *maxset)
535 return GetProcessWorkingSetSizeEx(process, minset, maxset, NULL);
539 /******************************************************************
540 * GetProcessIoCounters (KERNEL32.@)
542 BOOL WINAPI GetProcessIoCounters(HANDLE hProcess, PIO_COUNTERS ioc)
544 return set_ntstatus( NtQueryInformationProcess(hProcess, ProcessIoCounters, ioc, sizeof(*ioc), NULL ));
547 /******************************************************************
548 * QueryFullProcessImageNameA (KERNEL32.@)
550 BOOL WINAPI QueryFullProcessImageNameA(HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD pdwSize)
552 BOOL retval;
553 DWORD pdwSizeW = *pdwSize;
554 LPWSTR lpExeNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pdwSize * sizeof(WCHAR));
556 retval = QueryFullProcessImageNameW(hProcess, dwFlags, lpExeNameW, &pdwSizeW);
558 if(retval)
559 retval = (0 != WideCharToMultiByte(CP_ACP, 0, lpExeNameW, -1,
560 lpExeName, *pdwSize, NULL, NULL));
561 if(retval)
562 *pdwSize = strlen(lpExeName);
564 HeapFree(GetProcessHeap(), 0, lpExeNameW);
565 return retval;
568 /******************************************************************
569 * QueryFullProcessImageNameW (KERNEL32.@)
571 BOOL WINAPI QueryFullProcessImageNameW(HANDLE hProcess, DWORD dwFlags, LPWSTR lpExeName, PDWORD pdwSize)
573 BYTE buffer[sizeof(UNICODE_STRING) + MAX_PATH*sizeof(WCHAR)]; /* this buffer should be enough */
574 UNICODE_STRING *dynamic_buffer = NULL;
575 UNICODE_STRING *result = NULL;
576 NTSTATUS status;
577 DWORD needed;
579 /* FIXME: On Windows, ProcessImageFileName return an NT path. In Wine it
580 * is a DOS path and we depend on this. */
581 status = NtQueryInformationProcess(hProcess, ProcessImageFileName, buffer,
582 sizeof(buffer) - sizeof(WCHAR), &needed);
583 if (status == STATUS_INFO_LENGTH_MISMATCH)
585 dynamic_buffer = HeapAlloc(GetProcessHeap(), 0, needed + sizeof(WCHAR));
586 status = NtQueryInformationProcess(hProcess, ProcessImageFileName, (LPBYTE)dynamic_buffer, needed, &needed);
587 result = dynamic_buffer;
589 else
590 result = (PUNICODE_STRING)buffer;
592 if (status) goto cleanup;
594 if (dwFlags & PROCESS_NAME_NATIVE)
596 WCHAR drive[3];
597 WCHAR device[1024];
598 DWORD ntlen, devlen;
600 if (result->Buffer[1] != ':' || result->Buffer[0] < 'A' || result->Buffer[0] > 'Z')
602 /* We cannot convert it to an NT device path so fail */
603 status = STATUS_NO_SUCH_DEVICE;
604 goto cleanup;
607 /* Find this drive's NT device path */
608 drive[0] = result->Buffer[0];
609 drive[1] = ':';
610 drive[2] = 0;
611 if (!QueryDosDeviceW(drive, device, ARRAY_SIZE(device)))
613 status = STATUS_NO_SUCH_DEVICE;
614 goto cleanup;
617 devlen = lstrlenW(device);
618 ntlen = devlen + (result->Length/sizeof(WCHAR) - 2);
619 if (ntlen + 1 > *pdwSize)
621 status = STATUS_BUFFER_TOO_SMALL;
622 goto cleanup;
624 *pdwSize = ntlen;
626 memcpy(lpExeName, device, devlen * sizeof(*device));
627 memcpy(lpExeName + devlen, result->Buffer + 2, result->Length - 2 * sizeof(WCHAR));
628 lpExeName[*pdwSize] = 0;
629 TRACE("NT path: %s\n", debugstr_w(lpExeName));
631 else
633 if (result->Length/sizeof(WCHAR) + 1 > *pdwSize)
635 status = STATUS_BUFFER_TOO_SMALL;
636 goto cleanup;
639 *pdwSize = result->Length/sizeof(WCHAR);
640 memcpy( lpExeName, result->Buffer, result->Length );
641 lpExeName[*pdwSize] = 0;
644 cleanup:
645 HeapFree(GetProcessHeap(), 0, dynamic_buffer);
646 return set_ntstatus( status );
649 /***********************************************************************
650 * K32GetProcessImageFileNameA (KERNEL32.@)
652 DWORD WINAPI K32GetProcessImageFileNameA( HANDLE process, LPSTR file, DWORD size )
654 return QueryFullProcessImageNameA(process, PROCESS_NAME_NATIVE, file, &size) ? size : 0;
657 /***********************************************************************
658 * K32GetProcessImageFileNameW (KERNEL32.@)
660 DWORD WINAPI K32GetProcessImageFileNameW( HANDLE process, LPWSTR file, DWORD size )
662 return QueryFullProcessImageNameW(process, PROCESS_NAME_NATIVE, file, &size) ? size : 0;
665 /***********************************************************************
666 * K32EnumProcesses (KERNEL32.@)
668 BOOL WINAPI K32EnumProcesses(DWORD *lpdwProcessIDs, DWORD cb, DWORD *lpcbUsed)
670 SYSTEM_PROCESS_INFORMATION *spi;
671 ULONG size = 0x4000;
672 void *buf = NULL;
673 NTSTATUS status;
675 do {
676 size *= 2;
677 HeapFree(GetProcessHeap(), 0, buf);
678 buf = HeapAlloc(GetProcessHeap(), 0, size);
679 if (!buf)
680 return FALSE;
682 status = NtQuerySystemInformation(SystemProcessInformation, buf, size, NULL);
683 } while(status == STATUS_INFO_LENGTH_MISMATCH);
685 if (!set_ntstatus( status ))
687 HeapFree(GetProcessHeap(), 0, buf);
688 return FALSE;
691 spi = buf;
693 for (*lpcbUsed = 0; cb >= sizeof(DWORD); cb -= sizeof(DWORD))
695 *lpdwProcessIDs++ = HandleToUlong(spi->UniqueProcessId);
696 *lpcbUsed += sizeof(DWORD);
698 if (spi->NextEntryOffset == 0)
699 break;
701 spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset);
704 HeapFree(GetProcessHeap(), 0, buf);
705 return TRUE;
708 /***********************************************************************
709 * K32QueryWorkingSet (KERNEL32.@)
711 BOOL WINAPI K32QueryWorkingSet( HANDLE process, LPVOID buffer, DWORD size )
713 TRACE( "(%p, %p, %d)\n", process, buffer, size );
715 return set_ntstatus( NtQueryVirtualMemory( process, NULL, MemoryWorkingSetList, buffer, size, NULL ));
718 /***********************************************************************
719 * K32QueryWorkingSetEx (KERNEL32.@)
721 BOOL WINAPI K32QueryWorkingSetEx( HANDLE process, LPVOID buffer, DWORD size )
723 TRACE( "(%p, %p, %d)\n", process, buffer, size );
725 return set_ntstatus( NtQueryVirtualMemory( process, NULL, MemoryWorkingSetExInformation, buffer, size, NULL ));
728 /***********************************************************************
729 * K32GetProcessMemoryInfo (KERNEL32.@)
731 * Retrieve memory usage information for a given process
734 BOOL WINAPI K32GetProcessMemoryInfo(HANDLE process,
735 PPROCESS_MEMORY_COUNTERS pmc, DWORD cb)
737 VM_COUNTERS vmc;
739 if (cb < sizeof(PROCESS_MEMORY_COUNTERS))
741 SetLastError(ERROR_INSUFFICIENT_BUFFER);
742 return FALSE;
745 if (!set_ntstatus( NtQueryInformationProcess( process, ProcessVmCounters, &vmc, sizeof(vmc), NULL )))
746 return FALSE;
748 pmc->cb = sizeof(PROCESS_MEMORY_COUNTERS);
749 pmc->PageFaultCount = vmc.PageFaultCount;
750 pmc->PeakWorkingSetSize = vmc.PeakWorkingSetSize;
751 pmc->WorkingSetSize = vmc.WorkingSetSize;
752 pmc->QuotaPeakPagedPoolUsage = vmc.QuotaPeakPagedPoolUsage;
753 pmc->QuotaPagedPoolUsage = vmc.QuotaPagedPoolUsage;
754 pmc->QuotaPeakNonPagedPoolUsage = vmc.QuotaPeakNonPagedPoolUsage;
755 pmc->QuotaNonPagedPoolUsage = vmc.QuotaNonPagedPoolUsage;
756 pmc->PagefileUsage = vmc.PagefileUsage;
757 pmc->PeakPagefileUsage = vmc.PeakPagefileUsage;
759 return TRUE;
762 /***********************************************************************
763 * ProcessIdToSessionId (KERNEL32.@)
764 * This function is available on Terminal Server 4SP4 and Windows 2000
766 BOOL WINAPI ProcessIdToSessionId( DWORD procid, DWORD *sessionid_ptr )
768 if (procid != GetCurrentProcessId())
769 FIXME("Unsupported for other processes.\n");
771 *sessionid_ptr = NtCurrentTeb()->Peb->SessionId;
772 return TRUE;
776 /***********************************************************************
777 * RegisterServiceProcess (KERNEL32.@)
779 * A service process calls this function to ensure that it continues to run
780 * even after a user logged off.
782 DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType)
784 /* I don't think that Wine needs to do anything in this function */
785 return 1; /* success */
789 /***********************************************************************
790 * GetCurrentProcess (KERNEL32.@)
792 * Get a handle to the current process.
794 * PARAMS
795 * None.
797 * RETURNS
798 * A handle representing the current process.
800 HANDLE WINAPI KERNEL32_GetCurrentProcess(void)
802 return (HANDLE)~(ULONG_PTR)0;
805 /***********************************************************************
806 * CmdBatNotification (KERNEL32.@)
808 * Notifies the system that a batch file has started or finished.
810 * PARAMS
811 * bBatchRunning [I] TRUE if a batch file has started or
812 * FALSE if a batch file has finished executing.
814 * RETURNS
815 * Unknown.
817 BOOL WINAPI CmdBatNotification( BOOL bBatchRunning )
819 FIXME("%d\n", bBatchRunning);
820 return FALSE;
823 /***********************************************************************
824 * RegisterApplicationRestart (KERNEL32.@)
826 HRESULT WINAPI RegisterApplicationRestart(PCWSTR pwzCommandLine, DWORD dwFlags)
828 FIXME("(%s,%d)\n", debugstr_w(pwzCommandLine), dwFlags);
830 return S_OK;
833 /**********************************************************************
834 * WTSGetActiveConsoleSessionId (KERNEL32.@)
836 DWORD WINAPI WTSGetActiveConsoleSessionId(void)
838 static int once;
839 if (!once++) FIXME("stub\n");
840 /* Return current session id. */
841 return NtCurrentTeb()->Peb->SessionId;
844 /**********************************************************************
845 * GetSystemDEPPolicy (KERNEL32.@)
847 DEP_SYSTEM_POLICY_TYPE WINAPI GetSystemDEPPolicy(void)
849 FIXME("stub\n");
850 return OptIn;
853 /**********************************************************************
854 * SetProcessDEPPolicy (KERNEL32.@)
856 BOOL WINAPI SetProcessDEPPolicy(DWORD newDEP)
858 FIXME("(%d): stub\n", newDEP);
859 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
860 return FALSE;
863 /**********************************************************************
864 * ApplicationRecoveryFinished (KERNEL32.@)
866 VOID WINAPI ApplicationRecoveryFinished(BOOL success)
868 FIXME(": stub\n");
869 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
872 /**********************************************************************
873 * ApplicationRecoveryInProgress (KERNEL32.@)
875 HRESULT WINAPI ApplicationRecoveryInProgress(PBOOL canceled)
877 FIXME(":%p stub\n", canceled);
878 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
879 return E_FAIL;
882 /**********************************************************************
883 * RegisterApplicationRecoveryCallback (KERNEL32.@)
885 HRESULT WINAPI RegisterApplicationRecoveryCallback(APPLICATION_RECOVERY_CALLBACK callback, PVOID param, DWORD pingint, DWORD flags)
887 FIXME("%p, %p, %d, %d: stub, faking success\n", callback, param, pingint, flags);
888 return S_OK;
891 /***********************************************************************
892 * GetApplicationRestartSettings (KERNEL32.@)
894 HRESULT WINAPI GetApplicationRestartSettings(HANDLE process, WCHAR *cmdline, DWORD *size, DWORD *flags)
896 FIXME("%p, %p, %p, %p)\n", process, cmdline, size, flags);
897 return E_NOTIMPL;
900 /**********************************************************************
901 * GetNumaNodeProcessorMask (KERNEL32.@)
903 BOOL WINAPI GetNumaNodeProcessorMask(UCHAR node, PULONGLONG mask)
905 FIXME("(%c %p): stub\n", node, mask);
906 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
907 return FALSE;
910 /**********************************************************************
911 * GetNumaAvailableMemoryNode (KERNEL32.@)
913 BOOL WINAPI GetNumaAvailableMemoryNode(UCHAR node, PULONGLONG available_bytes)
915 FIXME("(%c %p): stub\n", node, available_bytes);
916 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
917 return FALSE;
920 /**********************************************************************
921 * GetNumaAvailableMemoryNodeEx (KERNEL32.@)
923 BOOL WINAPI GetNumaAvailableMemoryNodeEx(USHORT node, PULONGLONG available_bytes)
925 FIXME("(%hu %p): stub\n", node, available_bytes);
926 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
927 return FALSE;
930 /***********************************************************************
931 * GetNumaProcessorNode (KERNEL32.@)
933 BOOL WINAPI GetNumaProcessorNode(UCHAR processor, PUCHAR node)
935 SYSTEM_INFO si;
937 TRACE("(%d, %p)\n", processor, node);
939 GetSystemInfo( &si );
940 if (processor < si.dwNumberOfProcessors)
942 *node = 0;
943 return TRUE;
946 *node = 0xFF;
947 SetLastError(ERROR_INVALID_PARAMETER);
948 return FALSE;
951 /***********************************************************************
952 * GetNumaProcessorNodeEx (KERNEL32.@)
954 BOOL WINAPI GetNumaProcessorNodeEx(PPROCESSOR_NUMBER processor, PUSHORT node_number)
956 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
957 return FALSE;
960 /***********************************************************************
961 * GetNumaProximityNode (KERNEL32.@)
963 BOOL WINAPI GetNumaProximityNode(ULONG proximity_id, PUCHAR node_number)
965 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
966 return FALSE;
969 /**********************************************************************
970 * GetProcessDEPPolicy (KERNEL32.@)
972 BOOL WINAPI GetProcessDEPPolicy(HANDLE process, LPDWORD flags, PBOOL permanent)
974 ULONG dep_flags;
976 TRACE("(%p %p %p)\n", process, flags, permanent);
978 if (!set_ntstatus( NtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags,
979 &dep_flags, sizeof(dep_flags), NULL )))
980 return FALSE;
982 if (flags)
984 *flags = 0;
985 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
986 *flags |= PROCESS_DEP_ENABLE;
987 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION)
988 *flags |= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION;
991 if (permanent) *permanent = (dep_flags & MEM_EXECUTE_OPTION_PERMANENT) != 0;
992 return TRUE;
995 /**********************************************************************
996 * FlushProcessWriteBuffers (KERNEL32.@)
998 VOID WINAPI FlushProcessWriteBuffers(void)
1000 static int once = 0;
1002 if (!once++)
1003 FIXME(": stub\n");
1006 /***********************************************************************
1007 * UnregisterApplicationRestart (KERNEL32.@)
1009 HRESULT WINAPI UnregisterApplicationRestart(void)
1011 FIXME(": stub\n");
1012 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1013 return S_OK;
1016 /***********************************************************************
1017 * CreateUmsCompletionList (KERNEL32.@)
1019 BOOL WINAPI CreateUmsCompletionList(PUMS_COMPLETION_LIST *list)
1021 FIXME( "%p: stub\n", list );
1022 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1023 return FALSE;
1026 /***********************************************************************
1027 * CreateUmsThreadContext (KERNEL32.@)
1029 BOOL WINAPI CreateUmsThreadContext(PUMS_CONTEXT *ctx)
1031 FIXME( "%p: stub\n", ctx );
1032 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1033 return FALSE;
1036 /***********************************************************************
1037 * DeleteUmsCompletionList (KERNEL32.@)
1039 BOOL WINAPI DeleteUmsCompletionList(PUMS_COMPLETION_LIST list)
1041 FIXME( "%p: stub\n", list );
1042 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1043 return FALSE;
1046 /***********************************************************************
1047 * DeleteUmsThreadContext (KERNEL32.@)
1049 BOOL WINAPI DeleteUmsThreadContext(PUMS_CONTEXT ctx)
1051 FIXME( "%p: stub\n", ctx );
1052 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1053 return FALSE;
1056 /***********************************************************************
1057 * DequeueUmsCompletionListItems (KERNEL32.@)
1059 BOOL WINAPI DequeueUmsCompletionListItems(void *list, DWORD timeout, PUMS_CONTEXT *ctx)
1061 FIXME( "%p,%08x,%p: stub\n", list, timeout, ctx );
1062 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1063 return FALSE;
1066 /***********************************************************************
1067 * EnterUmsSchedulingMode (KERNEL32.@)
1069 BOOL WINAPI EnterUmsSchedulingMode(UMS_SCHEDULER_STARTUP_INFO *info)
1071 FIXME( "%p: stub\n", info );
1072 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1073 return FALSE;
1076 /***********************************************************************
1077 * ExecuteUmsThread (KERNEL32.@)
1079 BOOL WINAPI ExecuteUmsThread(PUMS_CONTEXT ctx)
1081 FIXME( "%p: stub\n", ctx );
1082 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1083 return FALSE;
1086 /***********************************************************************
1087 * GetCurrentUmsThread (KERNEL32.@)
1089 PUMS_CONTEXT WINAPI GetCurrentUmsThread(void)
1091 FIXME( "stub\n" );
1092 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1093 return FALSE;
1096 /***********************************************************************
1097 * GetNextUmsListItem (KERNEL32.@)
1099 PUMS_CONTEXT WINAPI GetNextUmsListItem(PUMS_CONTEXT ctx)
1101 FIXME( "%p: stub\n", ctx );
1102 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1103 return NULL;
1106 /***********************************************************************
1107 * GetUmsCompletionListEvent (KERNEL32.@)
1109 BOOL WINAPI GetUmsCompletionListEvent(PUMS_COMPLETION_LIST list, HANDLE *event)
1111 FIXME( "%p,%p: stub\n", list, event );
1112 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1113 return FALSE;
1116 /***********************************************************************
1117 * QueryUmsThreadInformation (KERNEL32.@)
1119 BOOL WINAPI QueryUmsThreadInformation(PUMS_CONTEXT ctx, UMS_THREAD_INFO_CLASS class,
1120 void *buf, ULONG length, ULONG *ret_length)
1122 FIXME( "%p,%08x,%p,%08x,%p: stub\n", ctx, class, buf, length, ret_length );
1123 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1124 return FALSE;
1127 /***********************************************************************
1128 * SetUmsThreadInformation (KERNEL32.@)
1130 BOOL WINAPI SetUmsThreadInformation(PUMS_CONTEXT ctx, UMS_THREAD_INFO_CLASS class,
1131 void *buf, ULONG length)
1133 FIXME( "%p,%08x,%p,%08x: stub\n", ctx, class, buf, length );
1134 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1135 return FALSE;
1138 /***********************************************************************
1139 * UmsThreadYield (KERNEL32.@)
1141 BOOL WINAPI UmsThreadYield(void *param)
1143 FIXME( "%p: stub\n", param );
1144 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
1145 return FALSE;
1148 /**********************************************************************
1149 * BaseFlushAppcompatCache (KERNEL32.@)
1151 BOOL WINAPI BaseFlushAppcompatCache(void)
1153 FIXME(": stub\n");
1154 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1155 return FALSE;