From 8e17bd8685fce1a0fc52bdd0765a60e14216b503 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 22 Feb 2007 18:01:13 +0000 Subject: [PATCH] * cygheap.h (struct cwdstuff): Remove sync member and keep_in_sync accessors. * external.cc (cygwin_internal): Drop call to cygheap->cwd.keep_in_sync. * fhandler_disk_file.cc (fhandler_disk_file::link): Always presume ability to create hard links. * path.cc (cwdstuff::init): Drop 9x considerations. (cwdstuff::keep_in_sync): Remove. (cwdstuff::set): Take NT for granted. * pinfo.h (cygwin_pid): Just return pid. * wincap.cc: Remove has_hard_links, can_open_directories, has_negative_pids, has_named_pipes, has_try_enter_critical_section, cant_debug_dll_entry and detect_win16_exe throughout. * wincap.h: Ditto. --- winsup/cygwin/ChangeLog | 16 +++ winsup/cygwin/cygheap.h | 3 - winsup/cygwin/external.cc | 1 - winsup/cygwin/fhandler_disk_file.cc | 159 ++++++++++++++-------------- winsup/cygwin/path.cc | 145 ++++++++++--------------- winsup/cygwin/pinfo.h | 2 +- winsup/cygwin/wincap.cc | 49 --------- winsup/cygwin/wincap.h | 14 --- 8 files changed, 149 insertions(+), 240 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 65ddb7b1c..5f506c907 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2007-02-22 Corinna Vinschen + + * cygheap.h (struct cwdstuff): Remove sync member and keep_in_sync + accessors. + * external.cc (cygwin_internal): Drop call to cygheap->cwd.keep_in_sync. + * fhandler_disk_file.cc (fhandler_disk_file::link): Always presume + ability to create hard links. + * path.cc (cwdstuff::init): Drop 9x considerations. + (cwdstuff::keep_in_sync): Remove. + (cwdstuff::set): Take NT for granted. + * pinfo.h (cygwin_pid): Just return pid. + * wincap.cc: Remove has_hard_links, can_open_directories, + has_negative_pids, has_named_pipes, has_try_enter_critical_section, + cant_debug_dll_entry and detect_win16_exe throughout. + * wincap.h: Ditto. + 2007-02-22 Corinna Vinschen * fhandler_console.cc (fhandler_console::read): Drop 9x specific diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 49df3ff95..58ed3739e 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -225,7 +225,6 @@ struct cwdstuff char *win32; DWORD hash; DWORD drive_length; - bool sync; static muto cwd_lock; char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH); DWORD get_hash (); @@ -240,8 +239,6 @@ struct cwdstuff void fixup_after_exec (char *, char *, DWORD); bool get_initial (); int set (const char *, const char *, bool); - bool keep_in_sync () const { return sync; } - void keep_in_sync (bool val); }; #ifdef DEBUGGING diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index 4cfa07fb3..a958955b4 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -346,7 +346,6 @@ cygwin_internal (cygwin_getinfo_types t, ...) try_to_debug (); break; case CW_SYNC_WINENV: - cygheap->cwd.keep_in_sync (true); sync_winenv (); return 0; case CW_CYGTLS_PADSIZE: diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index add222691..a7b51a2b7 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -883,95 +883,92 @@ fhandler_disk_file::link (const char *newpath) return -1; } - /* Try to make hard link first on Windows NT */ - if (wincap.has_hard_links ()) - { - if (CreateHardLinkA (newpc, pc, NULL)) - goto success; + if (CreateHardLinkA (newpc, pc, NULL)) + goto success; - /* There are two cases to consider: - - The FS doesn't support hard links ==> ERROR_INVALID_FUNCTION - We copy the file. - - CreateHardLinkA is not supported ==> ERROR_PROC_NOT_FOUND - In that case (<= NT4) we try the old-style method. - Any other error should be taken seriously. */ - if (GetLastError () == ERROR_INVALID_FUNCTION) + /* There are two cases to consider: + - The FS doesn't support hard links ==> ERROR_INVALID_FUNCTION + We copy the file. + - CreateHardLinkA is not supported ==> ERROR_PROC_NOT_FOUND + In that case (<= NT4) we try the old-style method. + Any other error should be taken seriously. */ + if (GetLastError () == ERROR_INVALID_FUNCTION) + { + syscall_printf ("FS doesn't support hard links: Copy file"); + goto docopy; + } + if (GetLastError () != ERROR_PROC_NOT_FOUND) + { + syscall_printf ("CreateHardLinkA failed"); + __seterrno (); + close (); + return -1; + } + + WIN32_STREAM_ID stream_id; + LPVOID context; + WCHAR wbuf[CYG_MAX_PATH]; + BOOL ret; + DWORD written, write_err, path_len, size; + + path_len = sys_mbstowcs (wbuf, newpc, CYG_MAX_PATH) * sizeof (WCHAR); + + stream_id.dwStreamId = BACKUP_LINK; + stream_id.dwStreamAttributes = 0; + stream_id.dwStreamNameSize = 0; + stream_id.Size.HighPart = 0; + stream_id.Size.LowPart = path_len; + size = sizeof (WIN32_STREAM_ID) - sizeof (WCHAR**) + + stream_id.dwStreamNameSize; + context = NULL; + write_err = 0; + /* Write WIN32_STREAM_ID */ + ret = BackupWrite (get_handle (), (LPBYTE) &stream_id, size, + &written, FALSE, FALSE, &context); + if (ret) + { + /* write the buffer containing the path */ + /* FIXME: BackupWrite sometimes traps if linkname is invalid. + Need to handle. */ + ret = BackupWrite (get_handle (), (LPBYTE) wbuf, path_len, + &written, FALSE, FALSE, &context); + if (!ret) + { + write_err = GetLastError (); + syscall_printf ("cannot write linkname, %E"); + } + /* Free context */ + BackupWrite (get_handle (), NULL, 0, &written, + TRUE, FALSE, &context); + } + else + { + write_err = GetLastError (); + syscall_printf ("cannot write stream_id, %E"); + } + + if (!ret) + { + /* Only copy file if FS doesn't support hard links */ + if (write_err == ERROR_INVALID_FUNCTION) { syscall_printf ("FS doesn't support hard links: Copy file"); goto docopy; } - if (GetLastError () != ERROR_PROC_NOT_FOUND) - { - syscall_printf ("CreateHardLinkA failed"); - __seterrno (); - close (); - return -1; - } - WIN32_STREAM_ID stream_id; - LPVOID context; - WCHAR wbuf[CYG_MAX_PATH]; - BOOL ret; - DWORD written, write_err, path_len, size; - - path_len = sys_mbstowcs (wbuf, newpc, CYG_MAX_PATH) * sizeof (WCHAR); - - stream_id.dwStreamId = BACKUP_LINK; - stream_id.dwStreamAttributes = 0; - stream_id.dwStreamNameSize = 0; - stream_id.Size.HighPart = 0; - stream_id.Size.LowPart = path_len; - size = sizeof (WIN32_STREAM_ID) - sizeof (WCHAR**) - + stream_id.dwStreamNameSize; - context = NULL; - write_err = 0; - /* Write WIN32_STREAM_ID */ - ret = BackupWrite (get_handle (), (LPBYTE) &stream_id, size, - &written, FALSE, FALSE, &context); - if (ret) - { - /* write the buffer containing the path */ - /* FIXME: BackupWrite sometimes traps if linkname is invalid. - Need to handle. */ - ret = BackupWrite (get_handle (), (LPBYTE) wbuf, path_len, - &written, FALSE, FALSE, &context); - if (!ret) - { - write_err = GetLastError (); - syscall_printf ("cannot write linkname, %E"); - } - /* Free context */ - BackupWrite (get_handle (), NULL, 0, &written, - TRUE, FALSE, &context); - } - else - { - write_err = GetLastError (); - syscall_printf ("cannot write stream_id, %E"); - } - - if (!ret) - { - /* Only copy file if FS doesn't support hard links */ - if (write_err == ERROR_INVALID_FUNCTION) - { - syscall_printf ("FS doesn't support hard links: Copy file"); - goto docopy; - } - - close (); - __seterrno_from_win_error (write_err); - return -1; - } - - success: close (); - if (!allow_winsymlinks && pc.is_lnk_special ()) - SetFileAttributes (newpc, (DWORD) pc - | FILE_ATTRIBUTE_SYSTEM - | FILE_ATTRIBUTE_READONLY); - return 0; + __seterrno_from_win_error (write_err); + return -1; } + +success: + close (); + if (!allow_winsymlinks && pc.is_lnk_special ()) + SetFileAttributes (newpc, (DWORD) pc + | FILE_ATTRIBUTE_SYSTEM + | FILE_ATTRIBUTE_READONLY); + return 0; + docopy: /* do this with a copy */ if (!CopyFileA (pc, newpc, 1)) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 68431276a..c0ad9a8d8 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -4187,28 +4187,11 @@ cwdstuff::init () { cwd_lock.init ("cwd_lock"); get_initial (); - if (!dynamically_loaded && !keep_in_sync ()) - { - /* Actually chdir into the system dir to avoid cwd problems on 9x. - See comment in cwdstuff::set below. */ - if (!wincap.can_open_directories ()) - SetCurrentDirectory (windows_system_directory); - else - close_user_proc_parms_cwd_handle (); - } + if (!dynamically_loaded) + close_user_proc_parms_cwd_handle (); cwd_lock.release (); } -void -cwdstuff::keep_in_sync (bool val) -{ - if (!wincap.can_open_directories ()) - { - sync = val; - SetCurrentDirectory (val ? win32 : windows_system_directory); - } -} - /* Get initial cwd. Should only be called once in a process tree. */ bool cwdstuff::get_initial () @@ -4236,81 +4219,61 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit) cwd_lock.acquire (); if (doit) { - if (keep_in_sync ()) + /* We utilize the user parameter block. The directory is + stored manually, but the handle to the directory is always + closed and set to NULL. This way the directory isn't blocked + even if it's the cwd of a Cygwin process. + + Why the hassle? + + - A process has always an open handle to the current working + directory which disallows manipulating this directory. + POSIX allows to remove a directory if the permissions are ok. + The fact that its the cwd of some process doesn't matter. + + - SetCurrentDirectory fails for directories with strict + permissions even for processes with the SE_BACKUP_NAME + privilege enabled. The reason is apparently that + SetCurrentDirectory calls NtOpenFile without the + FILE_OPEN_FOR_BACKUP_INTENT flag set. */ + HANDLE h; + DWORD attr = GetFileAttributes (win32_cwd); + if (attr == INVALID_FILE_ATTRIBUTES) { - /* If a Cygwin application called cygwin_internal(CW_SYNC_WINENV), - then it's about to call native Windows functions. This also - sets the keep_in_sync flag so that we actually chdir into the - native directory on 9x to avoid confusion. */ - if (!SetCurrentDirectory (win32_cwd)) - { - __seterrno (); - goto out; - } + set_errno (ENOENT); + goto out; } + if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) + { + set_errno (ENOTDIR); + goto out; + } + h = CreateFile (win32_cwd, FILE_TRAVERSE, FILE_SHARE_VALID_FLAGS, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (h == INVALID_HANDLE_VALUE) + { + __seterrno (); + goto out; + } + ULONG len = strlen (win32_cwd); + ANSI_STRING as = {len, len + 2, (PCHAR) alloca (len + 2)}; + strcpy (as.Buffer, win32_cwd); + if (as.Buffer[len - 1] != '\\') + { + strcpy (as.Buffer + len, "\\"); + ++as.Length; + } + if (current_codepage == ansi_cp) + RtlAnsiStringToUnicodeString ( + &get_user_proc_parms ()->CurrentDirectoryName, + &as, FALSE); else - { - /* We don't actually chdir on 9x but stay in the system dir. - - On NT we utilize the user parameter block. The directory is - stored manually, but the handle to the directory is always - closed and set to NULL. This way the directory isn't blocked - even if it's the cwd of a Cygwin process. - - Why the hassle? - - - A process has always an open handle to the current working - directory which disallows manipulating this directory. - POSIX allows to remove a directory if the permissions are ok. - The fact that its the cwd of some process doesn't matter. - - - SetCurrentDirectory fails for directories with strict - permissions even for processes with the SE_BACKUP_NAME - privilege enabled. The reason is apparently that - SetCurrentDirectory calls NtOpenFile without the - FILE_OPEN_FOR_BACKUP_INTENT flag set. */ - DWORD attr = GetFileAttributes (win32_cwd); - if (attr == INVALID_FILE_ATTRIBUTES) - { - set_errno (ENOENT); - goto out; - } - if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) - { - set_errno (ENOTDIR); - goto out; - } - if (wincap.can_open_directories ()) - { - HANDLE h = CreateFile (win32_cwd, FILE_TRAVERSE, - FILE_SHARE_VALID_FLAGS, NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (h == INVALID_HANDLE_VALUE) - { - __seterrno (); - goto out; - } - ULONG len = strlen (win32_cwd); - ANSI_STRING as = {len, len + 2, (PCHAR) alloca (len + 2)}; - strcpy (as.Buffer, win32_cwd); - if (as.Buffer[len - 1] != '\\') - { - strcpy (as.Buffer + len, "\\"); - ++as.Length; - } - if (current_codepage == ansi_cp) - RtlAnsiStringToUnicodeString ( - &get_user_proc_parms ()->CurrentDirectoryName, - &as, FALSE); - else - RtlOemStringToUnicodeString ( - &get_user_proc_parms ()->CurrentDirectoryName, - &as, FALSE); - close_user_proc_parms_cwd_handle (); - CloseHandle (h); - } - } + RtlOemStringToUnicodeString ( + &get_user_proc_parms ()->CurrentDirectoryName, + &as, FALSE); + close_user_proc_parms_cwd_handle (); + CloseHandle (h); } } /* If there is no win32 path or it has the form c:xxx, get the value */ diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index ee02a6180..95e8d2617 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -231,7 +231,7 @@ public: extern __inline pid_t cygwin_pid (pid_t pid) { - return (pid_t) (wincap.has_negative_pids ()) ? -(int) pid : pid; + return pid; } void __stdcall pinfo_init (char **, int); diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 0b481d3ce..9dcf11089 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -21,13 +21,8 @@ static NO_COPY wincaps wincap_unknown = { has_security_descriptor_control:false, has_ip_helper_lib:false, has_physical_mem_access:true, - has_hard_links:true, - can_open_directories:true, has_move_file_ex:true, - has_negative_pids:false, has_unreliable_pipes:false, - has_named_pipes:true, - has_try_enter_critical_section:true, has_raw_devices:true, has_valid_processorlevel:true, has_64bit_file_access:true, @@ -37,12 +32,10 @@ static NO_COPY wincaps wincap_unknown = { pty_needs_alloc_console:true, has_terminal_services:false, has_switch_to_thread:true, - cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:false, start_proc_suspended:false, has_extended_priority_class:false, has_guid_volumes:false, - detect_win16_exe:false, has_null_console_handler_routine:true, has_disk_ex_ioctls:false, has_disabled_user_tos_setting:false, @@ -67,13 +60,8 @@ static NO_COPY wincaps wincap_nt4 = { has_security_descriptor_control:false, has_ip_helper_lib:false, has_physical_mem_access:true, - has_hard_links:true, - can_open_directories:true, has_move_file_ex:true, - has_negative_pids:false, has_unreliable_pipes:false, - has_named_pipes:true, - has_try_enter_critical_section:true, has_raw_devices:true, has_valid_processorlevel:true, has_64bit_file_access:true, @@ -83,12 +71,10 @@ static NO_COPY wincaps wincap_nt4 = { pty_needs_alloc_console:true, has_terminal_services:false, has_switch_to_thread:true, - cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:false, start_proc_suspended:false, has_extended_priority_class:false, has_guid_volumes:false, - detect_win16_exe:false, has_null_console_handler_routine:true, has_disk_ex_ioctls:false, has_disabled_user_tos_setting:false, @@ -113,13 +99,8 @@ static NO_COPY wincaps wincap_nt4sp4 = { has_security_descriptor_control:false, has_ip_helper_lib:true, has_physical_mem_access:true, - has_hard_links:true, - can_open_directories:true, has_move_file_ex:true, - has_negative_pids:false, has_unreliable_pipes:false, - has_named_pipes:true, - has_try_enter_critical_section:true, has_raw_devices:true, has_valid_processorlevel:true, has_64bit_file_access:true, @@ -129,12 +110,10 @@ static NO_COPY wincaps wincap_nt4sp4 = { pty_needs_alloc_console:true, has_terminal_services:false, has_switch_to_thread:true, - cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:false, start_proc_suspended:false, has_extended_priority_class:false, has_guid_volumes:false, - detect_win16_exe:false, has_null_console_handler_routine:true, has_disk_ex_ioctls:false, has_disabled_user_tos_setting:false, @@ -159,13 +138,8 @@ static NO_COPY wincaps wincap_2000 = { has_security_descriptor_control:true, has_ip_helper_lib:true, has_physical_mem_access:true, - has_hard_links:true, - can_open_directories:true, has_move_file_ex:true, - has_negative_pids:false, has_unreliable_pipes:false, - has_named_pipes:true, - has_try_enter_critical_section:true, has_raw_devices:true, has_valid_processorlevel:true, has_64bit_file_access:true, @@ -175,12 +149,10 @@ static NO_COPY wincaps wincap_2000 = { pty_needs_alloc_console:true, has_terminal_services:true, has_switch_to_thread:true, - cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:false, start_proc_suspended:false, has_extended_priority_class:true, has_guid_volumes:true, - detect_win16_exe:false, has_null_console_handler_routine:true, has_disk_ex_ioctls:false, has_disabled_user_tos_setting:true, @@ -205,13 +177,8 @@ static NO_COPY wincaps wincap_xp = { has_security_descriptor_control:true, has_ip_helper_lib:true, has_physical_mem_access:true, - has_hard_links:true, - can_open_directories:true, has_move_file_ex:true, - has_negative_pids:false, has_unreliable_pipes:false, - has_named_pipes:true, - has_try_enter_critical_section:true, has_raw_devices:true, has_valid_processorlevel:true, has_64bit_file_access:true, @@ -221,12 +188,10 @@ static NO_COPY wincaps wincap_xp = { pty_needs_alloc_console:true, has_terminal_services:true, has_switch_to_thread:true, - cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:true, start_proc_suspended:false, has_extended_priority_class:true, has_guid_volumes:true, - detect_win16_exe:false, has_null_console_handler_routine:true, has_disk_ex_ioctls:true, has_disabled_user_tos_setting:true, @@ -251,13 +216,8 @@ static NO_COPY wincaps wincap_2003 = { has_security_descriptor_control:true, has_ip_helper_lib:true, has_physical_mem_access:false, - has_hard_links:true, - can_open_directories:true, has_move_file_ex:true, - has_negative_pids:false, has_unreliable_pipes:false, - has_named_pipes:true, - has_try_enter_critical_section:true, has_raw_devices:true, has_valid_processorlevel:true, has_64bit_file_access:true, @@ -267,12 +227,10 @@ static NO_COPY wincaps wincap_2003 = { pty_needs_alloc_console:true, has_terminal_services:true, has_switch_to_thread:true, - cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:true, start_proc_suspended:false, has_extended_priority_class:true, has_guid_volumes:true, - detect_win16_exe:false, has_null_console_handler_routine:true, has_disk_ex_ioctls:true, has_disabled_user_tos_setting:true, @@ -297,13 +255,8 @@ static NO_COPY wincaps wincap_vista = { has_security_descriptor_control:true, has_ip_helper_lib:true, has_physical_mem_access:false, - has_hard_links:true, - can_open_directories:true, has_move_file_ex:true, - has_negative_pids:false, has_unreliable_pipes:false, - has_named_pipes:true, - has_try_enter_critical_section:true, has_raw_devices:true, has_valid_processorlevel:true, has_64bit_file_access:true, @@ -313,12 +266,10 @@ static NO_COPY wincaps wincap_vista = { pty_needs_alloc_console:true, has_terminal_services:true, has_switch_to_thread:true, - cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:true, start_proc_suspended:false, has_extended_priority_class:true, has_guid_volumes:true, - detect_win16_exe:false, has_null_console_handler_routine:true, has_disk_ex_ioctls:true, has_disabled_user_tos_setting:true, diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index a3198cd06..d803f6b18 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -21,13 +21,8 @@ struct wincaps unsigned has_security_descriptor_control : 1; unsigned has_ip_helper_lib : 1; unsigned has_physical_mem_access : 1; - unsigned has_hard_links : 1; - unsigned can_open_directories : 1; unsigned has_move_file_ex : 1; - unsigned has_negative_pids : 1; unsigned has_unreliable_pipes : 1; - unsigned has_named_pipes : 1; - unsigned has_try_enter_critical_section : 1; unsigned has_raw_devices : 1; unsigned has_valid_processorlevel : 1; unsigned has_64bit_file_access : 1; @@ -37,12 +32,10 @@ struct wincaps unsigned pty_needs_alloc_console : 1; unsigned has_terminal_services : 1; unsigned has_switch_to_thread : 1; - unsigned cant_debug_dll_entry : 1; unsigned has_ioctl_storage_get_media_types_ex : 1; unsigned start_proc_suspended : 1; unsigned has_extended_priority_class : 1; unsigned has_guid_volumes : 1; - unsigned detect_win16_exe : 1; unsigned has_null_console_handler_routine : 1; unsigned has_disk_ex_ioctls : 1; unsigned has_disabled_user_tos_setting : 1; @@ -83,13 +76,8 @@ public: bool IMPLEMENT (has_security_descriptor_control) bool IMPLEMENT (has_ip_helper_lib) bool IMPLEMENT (has_physical_mem_access) - bool IMPLEMENT (has_hard_links) - bool IMPLEMENT (can_open_directories) bool IMPLEMENT (has_move_file_ex) - bool IMPLEMENT (has_negative_pids) bool IMPLEMENT (has_unreliable_pipes) - bool IMPLEMENT (has_named_pipes) - bool IMPLEMENT (has_try_enter_critical_section) bool IMPLEMENT (has_raw_devices) bool IMPLEMENT (has_valid_processorlevel) bool IMPLEMENT (has_64bit_file_access) @@ -99,12 +87,10 @@ public: bool IMPLEMENT (pty_needs_alloc_console) bool IMPLEMENT (has_terminal_services) bool IMPLEMENT (has_switch_to_thread) - bool IMPLEMENT (cant_debug_dll_entry) bool IMPLEMENT (has_ioctl_storage_get_media_types_ex) bool IMPLEMENT (start_proc_suspended) bool IMPLEMENT (has_extended_priority_class) bool IMPLEMENT (has_guid_volumes) - bool IMPLEMENT (detect_win16_exe) bool IMPLEMENT (has_null_console_handler_routine) bool IMPLEMENT (has_disk_ex_ioctls) bool IMPLEMENT (has_disabled_user_tos_setting)