diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 3f0784545c6..f1fc07a2ec7 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -735,7 +735,7 @@ @ stdcall IsDBCSLeadByteEx(long long) @ stdcall IsDebuggerPresent() @ stub IsLSCallback -# @ stub IsProcessInJob +@ stdcall IsProcessInJob(long long ptr) @ stdcall IsProcessorFeaturePresent(long) @ stub IsSLCallback @ stdcall IsSystemResumeAutomatic() @@ -822,8 +822,8 @@ @ stdcall OpenFile(str ptr long) @ stdcall OpenFileMappingA(long long str) @ stdcall OpenFileMappingW(long long wstr) -@ stub OpenJobObjectA -@ stub OpenJobObjectW +@ stdcall OpenJobObjectA(long long str) +@ stdcall OpenJobObjectW(long long wstr) @ stdcall OpenMutexA(long long str) @ stdcall OpenMutexW(long long wstr) @ stdcall OpenProcess(long long long) @@ -857,7 +857,7 @@ @ stdcall QueryDepthSList(ptr) ntdll.RtlQueryDepthSList @ stdcall QueryDosDeviceA(str ptr long) @ stdcall QueryDosDeviceW(wstr ptr long) -@ stub QueryInformationJobObject +@ stdcall QueryInformationJobObject(long long ptr long ptr) # @ stub QueryMemoryResourceNotification @ stub QueryNumberOfEventLogRecords @ stub QueryOldestEventLogRecord @@ -1014,7 +1014,7 @@ @ stdcall SetHandleContext(long long) @ stdcall SetHandleCount(long) @ stdcall SetHandleInformation(long long long) -@ stub SetInformationJobObject +@ stdcall SetInformationJobObject(long long ptr long) @ stub SetLastConsoleEventActive @ stdcall SetLastError(long) # @ stub SetLocalPrimaryComputerNameA @@ -1066,7 +1066,7 @@ @ stdcall SwitchToThread() @ stdcall SystemTimeToFileTime(ptr ptr) @ stdcall SystemTimeToTzSpecificLocalTime (ptr ptr ptr) -@ stub TerminateJobObject +@ stdcall TerminateJobObject(long long) @ stdcall TerminateProcess(long long) @ stdcall TerminateThread(long long) @ stdcall TermsrvAppInstallMode() diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c index bd6dd05d84a..1cc88b62ba2 100644 --- a/dlls/kernel32/sync.c +++ b/dlls/kernel32/sync.c @@ -898,6 +898,169 @@ BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous ) } +/* + * Jobs + */ + +/****************************************************************************** + * CreateJobObjectW (KERNEL32.@) + */ +HANDLE WINAPI CreateJobObjectW( LPSECURITY_ATTRIBUTES sa, LPCWSTR name ) +{ + HANDLE ret = 0; + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = OBJ_OPENIF | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0); + attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL; + attr.SecurityQualityOfService = NULL; + if (name) + { + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; + attr.RootDirectory = get_BaseNamedObjects_handle(); + } + + status = NtCreateJobObject( &ret, JOB_OBJECT_ALL_ACCESS, &attr ); + if (status == STATUS_OBJECT_NAME_EXISTS) + SetLastError( ERROR_ALREADY_EXISTS ); + else + SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + +/****************************************************************************** + * CreateJobObjectA (KERNEL32.@) + */ +HANDLE WINAPI CreateJobObjectA( LPSECURITY_ATTRIBUTES attr, LPCSTR name ) +{ + WCHAR buffer[MAX_PATH]; + + if (!name) return CreateJobObjectW( attr, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) + { + SetLastError( ERROR_FILENAME_EXCED_RANGE ); + return 0; + } + return CreateJobObjectW( attr, buffer ); +} + +/****************************************************************************** + * OpenJobObjectW (KERNEL32.@) + */ +HANDLE WINAPI OpenJobObjectW( DWORD access, BOOL inherit, LPCWSTR name ) +{ + HANDLE ret; + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = inherit ? OBJ_INHERIT : 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + if (name) + { + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; + attr.RootDirectory = get_BaseNamedObjects_handle(); + } + + status = NtOpenJobObject( &ret, access, &attr ); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return 0; + } + return ret; +} + +/****************************************************************************** + * OpenJobObjectA (KERNEL32.@) + */ +HANDLE WINAPI OpenJobObjectA( DWORD access, BOOL inherit, LPCSTR name ) +{ + WCHAR buffer[MAX_PATH]; + + if (!name) return OpenJobObjectW( access, inherit, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) + { + SetLastError( ERROR_FILENAME_EXCED_RANGE ); + return 0; + } + return OpenJobObjectW( access, inherit, buffer ); +} + +/****************************************************************************** + * TerminateJobObject (KERNEL32.@) + */ +BOOL WINAPI TerminateJobObject( HANDLE job, UINT exit_code ) +{ + NTSTATUS status = NtTerminateJobObject( job, exit_code ); + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; +} + +/****************************************************************************** + * QueryInformationJobObject (KERNEL32.@) + */ +BOOL WINAPI QueryInformationJobObject( HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info, + DWORD len, DWORD *ret_len ) +{ + NTSTATUS status = NtQueryInformationJobObject( job, class, info, len, ret_len ); + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; +} + +/****************************************************************************** + * SetInformationJobObject (KERNEL32.@) + */ +BOOL WINAPI SetInformationJobObject( HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info, DWORD len ) +{ + NTSTATUS status = NtSetInformationJobObject( job, class, info, len ); + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; +} + +/****************************************************************************** + * AssignProcessToJobObject (KERNEL32.@) + */ +BOOL WINAPI AssignProcessToJobObject( HANDLE job, HANDLE process ) +{ + NTSTATUS status = NtAssignProcessToJobObject( job, process ); + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; +} + +/****************************************************************************** + * IsProcessInJob (KERNEL32.@) + */ +BOOL WINAPI IsProcessInJob( HANDLE process, HANDLE job, PBOOL result ) +{ + NTSTATUS status = NtIsProcessInJob( job, process ); + switch(status) + { + case STATUS_PROCESS_IN_JOB: + *result = TRUE; + return TRUE; + case STATUS_PROCESS_NOT_IN_JOB: + *result = FALSE; + return TRUE; + default: + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } +} + + /* * Timers */ @@ -2007,55 +2170,6 @@ BOOL WINAPI BindIoCompletionCallback( HANDLE FileHandle, LPOVERLAPPED_COMPLETION return FALSE; } -/****************************************************************************** - * CreateJobObjectW (KERNEL32.@) - */ -HANDLE WINAPI CreateJobObjectW( LPSECURITY_ATTRIBUTES attr, LPCWSTR name ) -{ - FIXME("%p %s\n", attr, debugstr_w(name) ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - -/****************************************************************************** - * CreateJobObjectA (KERNEL32.@) - */ -HANDLE WINAPI CreateJobObjectA( LPSECURITY_ATTRIBUTES attr, LPCSTR name ) -{ - LPWSTR str = NULL; - UINT len; - HANDLE r; - - TRACE("%p %s\n", attr, debugstr_a(name) ); - - if( name ) - { - len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 ); - str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); - if( !str ) - { - SetLastError( ERROR_OUTOFMEMORY ); - return 0; - } - len = MultiByteToWideChar( CP_ACP, 0, name, -1, str, len ); - } - - r = CreateJobObjectW( attr, str ); - - HeapFree( GetProcessHeap(), 0, str ); - - return r; -} - -/****************************************************************************** - * AssignProcessToJobObject (KERNEL32.@) - */ -BOOL WINAPI AssignProcessToJobObject( HANDLE hJob, HANDLE hProcess ) -{ - FIXME("%p %p\n", hJob, hProcess); - return TRUE; -} - #ifdef __i386__ /*********************************************************************** diff --git a/include/winbase.h b/include/winbase.h index f7ccb8c7639..007d7b6a02b 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1811,6 +1811,7 @@ WINBASEAPI BOOL WINAPI IsWow64Process(HANDLE,PBOOL); WINADVAPI BOOL WINAPI ImpersonateLoggedOnUser(HANDLE); WINADVAPI BOOL WINAPI ImpersonateNamedPipeClient(HANDLE); WINADVAPI BOOL WINAPI ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL); +WINBASEAPI BOOL WINAPI IsProcessInJob(HANDLE,HANDLE,PBOOL); WINBASEAPI BOOL WINAPI IsProcessorFeaturePresent(DWORD); WINBASEAPI void WINAPI LeaveCriticalSection(CRITICAL_SECTION *lpCrit); WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR); @@ -1902,6 +1903,9 @@ WINBASEAPI HFILE WINAPI OpenFile(LPCSTR,OFSTRUCT*,UINT); WINBASEAPI HANDLE WINAPI OpenFileMappingA(DWORD,BOOL,LPCSTR); WINBASEAPI HANDLE WINAPI OpenFileMappingW(DWORD,BOOL,LPCWSTR); #define OpenFileMapping WINELIB_NAME_AW(OpenFileMapping) +WINBASEAPI HANDLE WINAPI OpenJobObjectA(DWORD,BOOL,LPCSTR); +WINBASEAPI HANDLE WINAPI OpenJobObjectW(DWORD,BOOL,LPCWSTR); +#define OpenJobObject WINELIB_NAME_AW(OpenJobObject) WINBASEAPI HANDLE WINAPI OpenMutexA(DWORD,BOOL,LPCSTR); WINBASEAPI HANDLE WINAPI OpenMutexW(DWORD,BOOL,LPCWSTR); #define OpenMutex WINELIB_NAME_AW(OpenMutex) @@ -1933,6 +1937,7 @@ WINBASEAPI USHORT WINAPI QueryDepthSList(PSLIST_HEADER); WINBASEAPI DWORD WINAPI QueryDosDeviceA(LPCSTR,LPSTR,DWORD); WINBASEAPI DWORD WINAPI QueryDosDeviceW(LPCWSTR,LPWSTR,DWORD); #define QueryDosDevice WINELIB_NAME_AW(QueryDosDevice) +WINBASEAPI BOOL WINAPI QueryInformationJobObject(HANDLE,JOBOBJECTINFOCLASS,LPVOID,DWORD,DWORD*); WINBASEAPI BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER*); WINBASEAPI BOOL WINAPI QueryPerformanceFrequency(LARGE_INTEGER*); WINBASEAPI DWORD WINAPI QueueUserAPC(PAPCFUNC,HANDLE,ULONG_PTR); @@ -2013,6 +2018,7 @@ WINADVAPI BOOL WINAPI SetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSEC WINBASEAPI BOOL WINAPI SetFileTime(HANDLE,const FILETIME*,const FILETIME*,const FILETIME*); WINBASEAPI UINT WINAPI SetHandleCount(UINT); WINBASEAPI BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD); +WINBASEAPI BOOL WINAPI SetInformationJobObject(HANDLE,JOBOBJECTINFOCLASS,LPVOID,DWORD); WINADVAPI BOOL WINAPI SetKernelObjectSecurity(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); WINBASEAPI BOOL WINAPI SetLocalTime(const SYSTEMTIME*); WINBASEAPI BOOL WINAPI SetMailslotInfo(HANDLE,DWORD); @@ -2062,6 +2068,7 @@ WINBASEAPI void WINAPI SwitchToFiber(LPVOID); WINBASEAPI BOOL WINAPI SwitchToThread(void); WINBASEAPI BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME); WINBASEAPI BOOL WINAPI SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); +WINBASEAPI BOOL WINAPI TerminateJobObject(HANDLE,UINT); WINBASEAPI BOOL WINAPI TerminateProcess(HANDLE,DWORD); WINBASEAPI BOOL WINAPI TerminateThread(HANDLE,DWORD); WINBASEAPI DWORD WINAPI TlsAlloc(void); diff --git a/include/winnt.h b/include/winnt.h index f4a0d70a0c9..87ab433788b 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -4008,6 +4008,13 @@ typedef enum tagSID_NAME_USE { #define MUTEX_MODIFY_STATE 0x0001 #define MUTEX_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1) +#define JOB_OBJECT_ASSIGN_PROCESS 0x0001 +#define JOB_OBJECT_SET_ATTRIBUTES 0x0002 +#define JOB_OBJECT_QUERY 0x0004 +#define JOB_OBJECT_TERMINATE 0x0008 +#define JOB_OBJECT_SET_SECURITY_ATTRIBUTES 0x0010 +#define JOB_OBJECT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1f) + #define TIMER_QUERY_STATE 0x0001 #define TIMER_MODIFY_STATE 0x0002 #define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) @@ -4901,6 +4908,21 @@ typedef enum _ACTIVATION_CONTEXT_INFO_CLASS { #define ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE 8 #define ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES 9 +typedef enum _JOBOBJECTINFOCLASS +{ + JobObjectBasicAccountingInformation = 1, + JobObjectBasicLimitInformation, + JobObjectBasicProcessIdList, + JobObjectBasicUIRestrictions, + JobObjectSecurityLimitInformation, + JobObjectEndOfJobTimeInformation, + JobObjectAssociateCompletionPortInformation, + JobObjectBasicAndIoAccountingInformation, + JobObjectExtendedLimitInformation, + JobObjectJobSetInformation, + MaxJobObjectInfoClass +} JOBOBJECTINFOCLASS; + #ifdef __cplusplus } #endif