diff --git a/dlls/api-ms-win-core-processenvironment-l1-1-0/api-ms-win-core-processenvironment-l1-1-0.spec b/dlls/api-ms-win-core-processenvironment-l1-1-0/api-ms-win-core-processenvironment-l1-1-0.spec index 7aeb821ed42..e3698d6efd1 100644 --- a/dlls/api-ms-win-core-processenvironment-l1-1-0/api-ms-win-core-processenvironment-l1-1-0.spec +++ b/dlls/api-ms-win-core-processenvironment-l1-1-0/api-ms-win-core-processenvironment-l1-1-0.spec @@ -19,4 +19,4 @@ @ stdcall SetEnvironmentVariableA(str str) kernel32.SetEnvironmentVariableA @ stdcall SetEnvironmentVariableW(wstr wstr) kernel32.SetEnvironmentVariableW @ stdcall SetStdHandle(long long) kernel32.SetStdHandle -@ stub SetStdHandleEx +@ stdcall SetStdHandleEx(long long ptr) kernel32.SetStdHandleEx diff --git a/dlls/api-ms-win-core-processenvironment-l1-2-0/api-ms-win-core-processenvironment-l1-2-0.spec b/dlls/api-ms-win-core-processenvironment-l1-2-0/api-ms-win-core-processenvironment-l1-2-0.spec index b319e7cb46b..2c25ee1a076 100644 --- a/dlls/api-ms-win-core-processenvironment-l1-2-0/api-ms-win-core-processenvironment-l1-2-0.spec +++ b/dlls/api-ms-win-core-processenvironment-l1-2-0/api-ms-win-core-processenvironment-l1-2-0.spec @@ -21,4 +21,4 @@ @ stdcall SetEnvironmentVariableA(str str) kernel32.SetEnvironmentVariableA @ stdcall SetEnvironmentVariableW(wstr wstr) kernel32.SetEnvironmentVariableW @ stdcall SetStdHandle(long long) kernel32.SetStdHandle -@ stub SetStdHandleEx +@ stdcall SetStdHandleEx(long long ptr) kernel32.SetStdHandleEx diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index d4ba5c71c13..41965827395 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -223,7 +223,7 @@ @ stdcall -import ClearCommBreak(long) @ stdcall -import ClearCommError(long ptr ptr) @ stdcall CloseConsoleHandle(long) -@ stdcall CloseHandle(long) +@ stdcall -import CloseHandle(long) # @ stub ClosePrivateNamespace @ stdcall CloseProfileUserMapping() @ stub CloseSystemHandle @@ -385,7 +385,7 @@ # @ stub DosPathToSessionPathA # @ stub DosPathToSessionPathW @ stdcall DuplicateConsoleHandle(long long long long) -@ stdcall DuplicateHandle(long long long ptr long long long) +@ stdcall -import DuplicateHandle(long long long ptr long long long) # @ stub EnableThreadProfiling @ stdcall EncodePointer(ptr) ntdll.RtlEncodePointer @ stdcall EncodeSystemPointer(ptr) ntdll.RtlEncodeSystemPointer @@ -695,7 +695,7 @@ @ stdcall GetGeoInfoA(long long ptr long long) @ stdcall GetGeoInfoW(long long ptr long long) @ stdcall GetHandleContext(long) -@ stdcall GetHandleInformation(long ptr) +@ stdcall -import GetHandleInformation(long ptr) @ stub -i386 GetLSCallbackTarget @ stub -i386 GetLSCallbackTemplate @ stdcall GetLargePageMinimum() @@ -1411,7 +1411,7 @@ # @ stub SetFirmwareEnvironmentVariableW @ stdcall SetHandleContext(long long) @ stdcall SetHandleCount(long) -@ stdcall SetHandleInformation(long long long) +@ stdcall -import SetHandleInformation(long long long) @ stdcall SetInformationJobObject(long long ptr long) @ stub SetLastConsoleEventActive @ stdcall SetLastError(long) RtlSetLastWin32Error diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 2781414a1f2..11ebde62e1f 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -3197,115 +3197,6 @@ DWORD WINAPI GetProcessFlags( DWORD processid ) } -/********************************************************************* - * CloseHandle (KERNEL32.@) - * - * Closes a handle. - * - * PARAMS - * handle [I] Handle to close. - * - * RETURNS - * Success: TRUE. - * Failure: FALSE, check GetLastError(). - */ -BOOL WINAPI CloseHandle( HANDLE handle ) -{ - NTSTATUS status; - - /* stdio handles need special treatment */ - if (handle == (HANDLE)STD_INPUT_HANDLE) - handle = InterlockedExchangePointer( &NtCurrentTeb()->Peb->ProcessParameters->hStdInput, 0 ); - else if (handle == (HANDLE)STD_OUTPUT_HANDLE) - handle = InterlockedExchangePointer( &NtCurrentTeb()->Peb->ProcessParameters->hStdOutput, 0 ); - else if (handle == (HANDLE)STD_ERROR_HANDLE) - handle = InterlockedExchangePointer( &NtCurrentTeb()->Peb->ProcessParameters->hStdError, 0 ); - - if (is_console_handle(handle)) - return CloseConsoleHandle(handle); - - status = NtClose( handle ); - if (status) SetLastError( RtlNtStatusToDosError(status) ); - return !status; -} - - -/********************************************************************* - * GetHandleInformation (KERNEL32.@) - */ -BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags ) -{ - OBJECT_DATA_INFORMATION info; - NTSTATUS status = NtQueryObject( handle, ObjectDataInformation, &info, sizeof(info), NULL ); - - if (status) SetLastError( RtlNtStatusToDosError(status) ); - else if (flags) - { - *flags = 0; - if (info.InheritHandle) *flags |= HANDLE_FLAG_INHERIT; - if (info.ProtectFromClose) *flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE; - } - return !status; -} - - -/********************************************************************* - * SetHandleInformation (KERNEL32.@) - */ -BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags ) -{ - OBJECT_DATA_INFORMATION info; - NTSTATUS status; - - /* if not setting both fields, retrieve current value first */ - if ((mask & (HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE)) != - (HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE)) - { - if ((status = NtQueryObject( handle, ObjectDataInformation, &info, sizeof(info), NULL ))) - { - SetLastError( RtlNtStatusToDosError(status) ); - return FALSE; - } - } - if (mask & HANDLE_FLAG_INHERIT) - info.InheritHandle = (flags & HANDLE_FLAG_INHERIT) != 0; - if (mask & HANDLE_FLAG_PROTECT_FROM_CLOSE) - info.ProtectFromClose = (flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) != 0; - - status = NtSetInformationObject( handle, ObjectDataInformation, &info, sizeof(info) ); - if (status) SetLastError( RtlNtStatusToDosError(status) ); - return !status; -} - - -/********************************************************************* - * DuplicateHandle (KERNEL32.@) - */ -BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source, - HANDLE dest_process, HANDLE *dest, - DWORD access, BOOL inherit, DWORD options ) -{ - NTSTATUS status; - - if (is_console_handle(source)) - { - /* FIXME: this test is not sufficient, we need to test process ids, not handles */ - if (source_process != dest_process || - source_process != GetCurrentProcess()) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - *dest = DuplicateConsoleHandle( source, access, inherit, options ); - return (*dest != INVALID_HANDLE_VALUE); - } - status = NtDuplicateObject( source_process, source, dest_process, dest, - access, inherit ? OBJ_INHERIT : 0, options ); - if (status) SetLastError( RtlNtStatusToDosError(status) ); - return !status; -} - - /*********************************************************************** * ConvertToGlobalHandle (KERNEL32.@) */ diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index 9d02d86ab94..615c0f434a1 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -56,12 +56,6 @@ static CRITICAL_SECTION console_section = { &critsect_debug, -1, 0, 0, 0, 0 }; static WCHAR input_exe[MAX_PATH + 1]; -/* map a real wineserver handle onto a kernel32 console handle */ -static inline HANDLE console_handle_map( HANDLE h ) -{ - return h != INVALID_HANDLE_VALUE ? (HANDLE)((UINT_PTR)h ^ 3) : INVALID_HANDLE_VALUE; -} - /* map a kernel32 console handle onto a real wineserver handle */ static inline obj_handle_t console_handle_unmap( HANDLE h ) { diff --git a/dlls/kernelbase/kernelbase.h b/dlls/kernelbase/kernelbase.h index abd33b6f1f8..78c4f581307 100644 --- a/dlls/kernelbase/kernelbase.h +++ b/dlls/kernelbase/kernelbase.h @@ -36,6 +36,12 @@ static inline BOOL is_console_handle(HANDLE h) return h != INVALID_HANDLE_VALUE && ((UINT_PTR)h & 3) == 3; } +/* map between ntdll handle and kernel32 console handle */ +static inline HANDLE console_handle_map( HANDLE h ) +{ + return h != INVALID_HANDLE_VALUE ? (HANDLE)((UINT_PTR)h ^ 3) : INVALID_HANDLE_VALUE; +} + static inline BOOL set_ntstatus( NTSTATUS status ) { if (status) SetLastError( RtlNtStatusToDosError( status )); diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 6beb796fac3..ac2bfe55dad 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -135,7 +135,7 @@ @ stdcall ClearCommBreak(long) @ stdcall ClearCommError(long ptr ptr) # @ stub CloseGlobalizationUserSettingsKey -@ stdcall CloseHandle(long) kernel32.CloseHandle +@ stdcall CloseHandle(long) # @ stub ClosePackageInfo # @ stub ClosePrivateNamespace # @ stub CloseState @@ -279,7 +279,7 @@ # @ stub DsReadNgcKeyW # @ stub DsUnBindW # @ stub DsWriteNgcKeyW -@ stdcall DuplicateHandle(long long long ptr long long long) kernel32.DuplicateHandle +@ stdcall DuplicateHandle(long long long ptr long long long) # @ stub DuplicateStateContainerHandle @ stdcall DuplicateToken(long long ptr) @ stdcall DuplicateTokenEx(long long ptr long long ptr) @@ -531,7 +531,7 @@ # @ stub GetGPOListInternalA # @ stub GetGPOListInternalW @ stdcall GetGeoInfoW(long long ptr long long) kernel32.GetGeoInfoW -@ stdcall GetHandleInformation(long ptr) kernel32.GetHandleInformation +@ stdcall GetHandleInformation(long ptr) # @ stub GetHivePath # @ stub GetIntegratedDisplaySize # @ stub GetIsEdpEnabled @@ -1440,8 +1440,8 @@ @ stdcall SetFileSecurityW(wstr long ptr) @ stdcall SetFileTime(long ptr ptr ptr) @ stdcall SetFileValidData(ptr int64) -@ stdcall SetHandleCount(long) kernel32.SetHandleCount -@ stdcall SetHandleInformation(long long long) kernel32.SetHandleInformation +@ stdcall SetHandleCount(long) +@ stdcall SetHandleInformation(long long long) # @ stub SetIsDeveloperModeEnabled # @ stub SetIsSideloadingEnabled @ stdcall SetKernelObjectSecurity(long long ptr) diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c index 7204420e25a..23480f6823a 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -42,6 +42,44 @@ static DWORD shutdown_priority = 0x280; ***********************************************************************/ +/********************************************************************* + * CloseHandle (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH CloseHandle( HANDLE handle ) +{ + if (handle == (HANDLE)STD_INPUT_HANDLE) + handle = InterlockedExchangePointer( &NtCurrentTeb()->Peb->ProcessParameters->hStdInput, 0 ); + else if (handle == (HANDLE)STD_OUTPUT_HANDLE) + handle = InterlockedExchangePointer( &NtCurrentTeb()->Peb->ProcessParameters->hStdOutput, 0 ); + else if (handle == (HANDLE)STD_ERROR_HANDLE) + handle = InterlockedExchangePointer( &NtCurrentTeb()->Peb->ProcessParameters->hStdError, 0 ); + + if (is_console_handle( handle )) handle = console_handle_map( handle ); + return set_ntstatus( NtClose( handle )); +} + + +/********************************************************************* + * DuplicateHandle (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH DuplicateHandle( HANDLE source_process, HANDLE source, + HANDLE dest_process, HANDLE *dest, + DWORD access, BOOL inherit, DWORD options ) +{ + if (is_console_handle( source )) + { + source = console_handle_map( source ); + if (!set_ntstatus( NtDuplicateObject( source_process, source, dest_process, dest, + access, inherit ? OBJ_INHERIT : 0, options ))) + return FALSE; + *dest = console_handle_map( *dest ); + return TRUE; + } + return set_ntstatus( NtDuplicateObject( source_process, source, dest_process, dest, + access, inherit ? OBJ_INHERIT : 0, options )); +} + + /**************************************************************************** * FlushInstructionCache (kernelbase.@) */ @@ -96,6 +134,26 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetExitCodeProcess( HANDLE process, LPDWORD exit_c } +/********************************************************************* + * GetHandleInformation (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH GetHandleInformation( HANDLE handle, DWORD *flags ) +{ + OBJECT_DATA_INFORMATION info; + + if (!set_ntstatus( NtQueryObject( handle, ObjectDataInformation, &info, sizeof(info), NULL ))) + return FALSE; + + if (flags) + { + *flags = 0; + if (info.InheritHandle) *flags |= HANDLE_FLAG_INHERIT; + if (info.ProtectFromClose) *flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE; + } + return TRUE; +} + + /*********************************************************************** * GetPriorityClass (kernelbase.@) */ @@ -254,6 +312,38 @@ UINT WINAPI DECLSPEC_HOTPATCH SetErrorMode( UINT mode ) } +/************************************************************************* + * SetHandleCount (kernelbase.@) + */ +UINT WINAPI DECLSPEC_HOTPATCH SetHandleCount( UINT count ) +{ + return count; +} + + +/********************************************************************* + * SetHandleInformation (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags ) +{ + OBJECT_DATA_INFORMATION info; + + /* if not setting both fields, retrieve current value first */ + if ((mask & (HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE)) != + (HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE)) + { + if (!set_ntstatus( NtQueryObject( handle, ObjectDataInformation, &info, sizeof(info), NULL ))) + return FALSE; + } + if (mask & HANDLE_FLAG_INHERIT) + info.InheritHandle = (flags & HANDLE_FLAG_INHERIT) != 0; + if (mask & HANDLE_FLAG_PROTECT_FROM_CLOSE) + info.ProtectFromClose = (flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) != 0; + + return set_ntstatus( NtSetInformationObject( handle, ObjectDataInformation, &info, sizeof(info) )); +} + + /*********************************************************************** * SetPriorityClass (kernelbase.@) */