ntdll: Use char pointers instead of ANSI/UNICODE_STRING in unix_to_nt_file_name().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-09 10:01:19 +02:00
parent 368e3a93b8
commit 5ebdeaaa37
4 changed files with 79 additions and 74 deletions

View File

@ -1057,16 +1057,14 @@ static void append_envW( WCHAR *env, SIZE_T *pos, const char *name, const WCHAR
/* set an environment variable for one of the wine path variables */ /* set an environment variable for one of the wine path variables */
static void add_path_var( WCHAR *env, SIZE_T *pos, const char *name, const char *path ) static void add_path_var( WCHAR *env, SIZE_T *pos, const char *name, const char *path )
{ {
UNICODE_STRING nt_name; WCHAR *nt_name;
ANSI_STRING unix_name;
if (!path) append_envW( env, pos, name, NULL ); if (!path) append_envW( env, pos, name, NULL );
else else
{ {
RtlInitAnsiString( &unix_name, path ); if (unix_to_nt_file_name( path, &nt_name )) return;
if (unix_to_nt_file_name( &unix_name, &nt_name )) return; append_envW( env, pos, name, nt_name );
append_envW( env, pos, name, nt_name.Buffer ); RtlFreeHeap( GetProcessHeap(), 0, nt_name );
RtlFreeUnicodeString( &nt_name );
} }
} }
@ -1202,25 +1200,24 @@ void CDECL get_initial_directory( UNICODE_STRING *dir )
if (pwd) if (pwd)
{ {
ANSI_STRING unix_name; WCHAR *nt_name;
UNICODE_STRING nt_name;
RtlInitAnsiString( &unix_name, pwd ); if (!unix_to_nt_file_name( pwd, &nt_name ))
if (!unix_to_nt_file_name( &unix_name, &nt_name ))
{ {
/* skip the \??\ prefix */ /* skip the \??\ prefix */
if (nt_name.Length > 6 * sizeof(WCHAR) && nt_name.Buffer[5] == ':') ULONG len = wcslen( nt_name );
if (len > 6 && nt_name[5] == ':')
{ {
dir->Length = nt_name.Length - 4 * sizeof(WCHAR); dir->Length = (len - 4) * sizeof(WCHAR);
memcpy( dir->Buffer, nt_name.Buffer + 4, dir->Length ); memcpy( dir->Buffer, nt_name + 4, dir->Length );
} }
else /* change \??\ to \\?\ */ else /* change \??\ to \\?\ */
{ {
dir->Length = nt_name.Length; dir->Length = len * sizeof(WCHAR);
memcpy( dir->Buffer, nt_name.Buffer, dir->Length ); memcpy( dir->Buffer, nt_name, dir->Length );
dir->Buffer[1] = '\\'; dir->Buffer[1] = '\\';
} }
RtlFreeUnicodeString( &nt_name ); RtlFreeHeap( GetProcessHeap(), 0, nt_name );
} }
} }

View File

@ -1767,7 +1767,7 @@ static NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr,
} }
static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) static NTSTATUS server_get_unix_name( HANDLE handle, char **unix_name )
{ {
data_size_t size = 1024; data_size_t size = 1024;
NTSTATUS ret; NTSTATUS ret;
@ -1777,7 +1777,6 @@ static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
{ {
name = RtlAllocateHeap( GetProcessHeap(), 0, size + 1 ); name = RtlAllocateHeap( GetProcessHeap(), 0, size + 1 );
if (!name) return STATUS_NO_MEMORY; if (!name) return STATUS_NO_MEMORY;
unix_name->MaximumLength = size + 1;
SERVER_START_REQ( get_handle_unix_name ) SERVER_START_REQ( get_handle_unix_name )
{ {
@ -1791,8 +1790,7 @@ static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
if (!ret) if (!ret)
{ {
name[size] = 0; name[size] = 0;
unix_name->Buffer = name; *unix_name = name;
unix_name->Length = size;
break; break;
} }
RtlFreeHeap( GetProcessHeap(), 0, name ); RtlFreeHeap( GetProcessHeap(), 0, name );
@ -1801,15 +1799,15 @@ static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
return ret; return ret;
} }
static NTSTATUS fill_name_info( const ANSI_STRING *unix_name, FILE_NAME_INFORMATION *info, LONG *name_len ) static NTSTATUS fill_name_info( const char *unix_name, FILE_NAME_INFORMATION *info, LONG *name_len )
{ {
UNICODE_STRING nt_name; WCHAR *nt_name;
NTSTATUS status; NTSTATUS status;
if (!(status = unix_to_nt_file_name( unix_name, &nt_name ))) if (!(status = unix_to_nt_file_name( unix_name, &nt_name )))
{ {
const WCHAR *ptr = nt_name.Buffer; const WCHAR *ptr = nt_name;
const WCHAR *end = ptr + (nt_name.Length / sizeof(WCHAR)); const WCHAR *end = ptr + wcslen( nt_name );
/* Skip the volume mount point. */ /* Skip the volume mount point. */
while (ptr != end && *ptr == '\\') ++ptr; while (ptr != end && *ptr == '\\') ++ptr;
@ -1822,7 +1820,7 @@ static NTSTATUS fill_name_info( const ANSI_STRING *unix_name, FILE_NAME_INFORMAT
else *name_len = info->FileNameLength; else *name_len = info->FileNameLength;
memcpy( info->FileName, ptr, *name_len ); memcpy( info->FileName, ptr, *name_len );
RtlFreeUnicodeString( &nt_name ); RtlFreeHeap( GetProcessHeap(), 0, nt_name );
} }
return status; return status;
@ -1953,7 +1951,7 @@ static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd )
struct mountmgr_unix_drive *drive; struct mountmgr_unix_drive *drive;
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
UNICODE_STRING string; UNICODE_STRING string;
ANSI_STRING unix_name; char *unix_name;
IO_STATUS_BLOCK io; IO_STATUS_BLOCK io;
HANDLE mountmgr; HANDLE mountmgr;
NTSTATUS status; NTSTATUS status;
@ -1962,8 +1960,8 @@ static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd )
if (server_get_unix_name( handle, &unix_name )) if (server_get_unix_name( handle, &unix_name ))
return NULL; return NULL;
letter = find_dos_device( unix_name.Buffer ); letter = find_dos_device( unix_name );
RtlFreeAnsiString( &unix_name ); RtlFreeHeap( GetProcessHeap(), 0, unix_name );
if (!(drive = RtlAllocateHeap( GetProcessHeap(), 0, 1024 ))) if (!(drive = RtlAllocateHeap( GetProcessHeap(), 0, 1024 )))
return NULL; return NULL;
@ -3447,19 +3445,19 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, char *nam
/****************************************************************** /******************************************************************
* unix_to_nt_file_name * unix_to_nt_file_name
*/ */
NTSTATUS CDECL unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt ) NTSTATUS unix_to_nt_file_name( const char *name, WCHAR **nt )
{ {
static const WCHAR unix_prefixW[] = {'\\','?','?','\\','u','n','i','x',0}; static const WCHAR unix_prefixW[] = {'\\','?','?','\\','u','n','i','x',0};
WCHAR dos_prefixW[] = {'\\','?','?','\\','A',':','\\',0}; WCHAR dos_prefixW[] = {'\\','?','?','\\','A',':','\\',0};
const WCHAR *prefix = unix_prefixW; const WCHAR *prefix = unix_prefixW;
unsigned int lenW, lenA = name->Length; unsigned int lenW, lenA = strlen(name);
const char *path = name->Buffer; const char *path = name;
NTSTATUS status; NTSTATUS status;
WCHAR *p; WCHAR *p, *buffer;
int drive; int drive;
status = find_drive_rootA( &path, lenA, &drive ); status = find_drive_rootA( &path, lenA, &drive );
lenA -= (path - name->Buffer); lenA -= path - name;
if (status == STATUS_SUCCESS) if (status == STATUS_SUCCESS)
{ {
@ -3470,18 +3468,29 @@ NTSTATUS CDECL unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt
else if (status != STATUS_OBJECT_PATH_NOT_FOUND) return status; else if (status != STATUS_OBJECT_PATH_NOT_FOUND) return status;
lenW = wcslen( prefix ); lenW = wcslen( prefix );
if (!(nt->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, (lenA + lenW + 1) * sizeof(WCHAR) ))) if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0, (lenA + lenW + 1) * sizeof(WCHAR) )))
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
memcpy( nt->Buffer, prefix, lenW * sizeof(WCHAR) ); memcpy( buffer, prefix, lenW * sizeof(WCHAR) );
lenW += ntdll_umbstowcs( path, lenA, nt->Buffer + lenW, lenA ); lenW += ntdll_umbstowcs( path, lenA, buffer + lenW, lenA );
nt->Buffer[lenW] = 0; buffer[lenW] = 0;
nt->Length = lenW * sizeof(WCHAR); for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
nt->MaximumLength = nt->Length + sizeof(WCHAR); *nt = buffer;
for (p = nt->Buffer; *p; p++) if (*p == '/') *p = '\\';
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/******************************************************************
* wine_unix_to_nt_file_name
*/
NTSTATUS CDECL wine_unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt )
{
WCHAR *nt_name = NULL;
NTSTATUS status = unix_to_nt_file_name( name->Buffer, &nt_name );
if (nt_name) RtlInitUnicodeString( nt, nt_name );
return status;
}
/*********************************************************************** /***********************************************************************
* unmount_device * unmount_device
* *
@ -3974,7 +3983,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
case FileAllInformation: case FileAllInformation:
{ {
FILE_ALL_INFORMATION *info = ptr; FILE_ALL_INFORMATION *info = ptr;
ANSI_STRING unix_name; char *unix_name;
if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = errno_to_status( errno ); if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = errno_to_status( errno );
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
@ -3991,8 +4000,8 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
info->ModeInformation.Mode = 0; /* FIXME */ info->ModeInformation.Mode = 0; /* FIXME */
info->AlignmentInformation.AlignmentRequirement = 1; /* FIXME */ info->AlignmentInformation.AlignmentRequirement = 1; /* FIXME */
io->u.Status = fill_name_info( &unix_name, &info->NameInformation, &name_len ); io->u.Status = fill_name_info( unix_name, &info->NameInformation, &name_len );
RtlFreeAnsiString( &unix_name ); RtlFreeHeap( GetProcessHeap(), 0, unix_name );
io->Information = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + name_len; io->Information = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + name_len;
} }
} }
@ -4038,13 +4047,13 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
case FileNameInformation: case FileNameInformation:
{ {
FILE_NAME_INFORMATION *info = ptr; FILE_NAME_INFORMATION *info = ptr;
ANSI_STRING unix_name; char *unix_name;
if (!(io->u.Status = server_get_unix_name( handle, &unix_name ))) if (!(io->u.Status = server_get_unix_name( handle, &unix_name )))
{ {
LONG name_len = len - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName); LONG name_len = len - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
io->u.Status = fill_name_info( &unix_name, info, &name_len ); io->u.Status = fill_name_info( unix_name, info, &name_len );
RtlFreeAnsiString( &unix_name ); RtlFreeHeap( GetProcessHeap(), 0, unix_name );
io->Information = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + name_len; io->Information = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + name_len;
} }
} }
@ -4052,14 +4061,14 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
case FileNetworkOpenInformation: case FileNetworkOpenInformation:
{ {
FILE_NETWORK_OPEN_INFORMATION *info = ptr; FILE_NETWORK_OPEN_INFORMATION *info = ptr;
ANSI_STRING unix_name; char *unix_name;
if (!(io->u.Status = server_get_unix_name( handle, &unix_name ))) if (!(io->u.Status = server_get_unix_name( handle, &unix_name )))
{ {
ULONG attributes; ULONG attributes;
struct stat st; struct stat st;
if (get_file_info( unix_name.Buffer, &st, &attributes ) == -1) if (get_file_info( unix_name, &st, &attributes ) == -1)
io->u.Status = errno_to_status( errno ); io->u.Status = errno_to_status( errno );
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS; io->u.Status = STATUS_INVALID_INFO_CLASS;
@ -4079,7 +4088,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
info->EndOfFile = std.EndOfFile; info->EndOfFile = std.EndOfFile;
info->FileAttributes = basic.FileAttributes; info->FileAttributes = basic.FileAttributes;
} }
RtlFreeAnsiString( &unix_name ); RtlFreeHeap( GetProcessHeap(), 0, unix_name );
} }
} }
break; break;
@ -6384,29 +6393,29 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
case ObjectNameInformation: case ObjectNameInformation:
{ {
OBJECT_NAME_INFORMATION *p = ptr; OBJECT_NAME_INFORMATION *p = ptr;
ANSI_STRING unix_name; char *unix_name;
WCHAR *nt_name;
/* first try as a file object */ /* first try as a file object */
if (!(status = server_get_unix_name( handle, &unix_name ))) if (!(status = server_get_unix_name( handle, &unix_name )))
{ {
UNICODE_STRING nt_name; if (!(status = unix_to_nt_file_name( unix_name, &nt_name )))
if (!(status = unix_to_nt_file_name( &unix_name, &nt_name )))
{ {
ULONG size = (wcslen(nt_name) + 1) * sizeof(WCHAR);
if (len < sizeof(*p)) status = STATUS_INFO_LENGTH_MISMATCH; if (len < sizeof(*p)) status = STATUS_INFO_LENGTH_MISMATCH;
else if (len < sizeof(*p) + nt_name.MaximumLength) status = STATUS_BUFFER_OVERFLOW; else if (len < sizeof(*p) + size) status = STATUS_BUFFER_OVERFLOW;
else else
{ {
p->Name.Buffer = (WCHAR *)(p + 1); p->Name.Buffer = (WCHAR *)(p + 1);
p->Name.Length = nt_name.Length; p->Name.Length = size - sizeof(WCHAR);
p->Name.MaximumLength = nt_name.MaximumLength; p->Name.MaximumLength = size;
memcpy( p->Name.Buffer, nt_name.Buffer, nt_name.MaximumLength ); wcscpy( p->Name.Buffer, nt_name );
} }
if (used_len) *used_len = sizeof(*p) + nt_name.MaximumLength; if (used_len) *used_len = sizeof(*p) + size;
RtlFreeUnicodeString( &nt_name ); RtlFreeHeap( GetProcessHeap(), 0, nt_name );
} }
RtlFreeAnsiString( &unix_name ); RtlFreeHeap( GetProcessHeap(), 0, unix_name );
break; break;
} }
else if (status != STATUS_OBJECT_TYPE_MISMATCH) break; else if (status != STATUS_OBJECT_TYPE_MISMATCH) break;

View File

@ -990,19 +990,21 @@ static inline char *prepend( char *buffer, const char *str, size_t len )
* *
* Open a file for a new dll. Helper for find_dll_file. * Open a file for a new dll. Helper for find_dll_file.
*/ */
static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, void **module, pe_image_info_t *image_info ) static NTSTATUS open_dll_file( const WCHAR *name, void **module, pe_image_info_t *image_info )
{ {
struct builtin_module *builtin; struct builtin_module *builtin;
FILE_BASIC_INFORMATION info; FILE_BASIC_INFORMATION info;
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io; IO_STATUS_BLOCK io;
UNICODE_STRING nt_name;
LARGE_INTEGER size; LARGE_INTEGER size;
FILE_OBJECTID_BUFFER id; FILE_OBJECTID_BUFFER id;
SIZE_T len = 0; SIZE_T len = 0;
NTSTATUS status; NTSTATUS status;
HANDLE handle, mapping; HANDLE handle, mapping;
InitializeObjectAttributes( &attr, nt_name, OBJ_CASE_INSENSITIVE, 0, NULL ); RtlInitUnicodeString( &nt_name, name );
InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE, 0, NULL );
if ((status = NtOpenFile( &handle, GENERIC_READ | SYNCHRONIZE, &attr, &io, if ((status = NtOpenFile( &handle, GENERIC_READ | SYNCHRONIZE, &attr, &io,
FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_SHARE_READ | FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE ))) FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE )))
@ -1024,7 +1026,7 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, void **module, pe_image_
{ {
if (!memcmp( &builtin->id, id.ObjectId, sizeof(builtin->id) )) if (!memcmp( &builtin->id, id.ObjectId, sizeof(builtin->id) ))
{ {
TRACE( "%s is the same file as existing module %p\n", debugstr_w( nt_name->Buffer ), TRACE( "%s is the same file as existing module %p\n", debugstr_w(name),
builtin->module ); builtin->module );
NtClose( handle ); NtClose( handle );
NtUnmapViewOfSection( NtCurrentProcess(), *module ); NtUnmapViewOfSection( NtCurrentProcess(), *module );
@ -1055,12 +1057,12 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, void **module, pe_image_
/* ignore non-builtins */ /* ignore non-builtins */
if (!(image_info->image_flags & IMAGE_FLAGS_WineBuiltin)) if (!(image_info->image_flags & IMAGE_FLAGS_WineBuiltin))
{ {
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_us(nt_name) ); WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_w(name) );
status = STATUS_DLL_NOT_FOUND; status = STATUS_DLL_NOT_FOUND;
} }
else if (image_info->cpu != client_cpu) else if (image_info->cpu != client_cpu)
{ {
TRACE( "%s is for CPU %u, continuing search\n", debugstr_us(nt_name), image_info->cpu ); TRACE( "%s is for CPU %u, continuing search\n", debugstr_w(name), image_info->cpu );
status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
} }
@ -1080,17 +1082,14 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, void **module, pe_image_
*/ */
static NTSTATUS open_builtin_file( char *name, void **module, pe_image_info_t *image_info ) static NTSTATUS open_builtin_file( char *name, void **module, pe_image_info_t *image_info )
{ {
ANSI_STRING strA; WCHAR *nt_name = NULL;
UNICODE_STRING nt_name;
NTSTATUS status; NTSTATUS status;
int fd; int fd;
nt_name.Buffer = NULL; if ((status = unix_to_nt_file_name( name, &nt_name ))) return status;
RtlInitAnsiString( &strA, name );
if ((status = unix_to_nt_file_name( &strA, &nt_name ))) return status;
status = open_dll_file( &nt_name, module, image_info ); status = open_dll_file( nt_name, module, image_info );
RtlFreeUnicodeString( &nt_name ); RtlFreeHeap( GetProcessHeap(), 0, nt_name );
if (status != STATUS_DLL_NOT_FOUND) return status; if (status != STATUS_DLL_NOT_FOUND) return status;
@ -1534,7 +1533,7 @@ static struct unix_funcs unix_funcs =
server_release_fd, server_release_fd,
server_init_process_done, server_init_process_done,
wine_nt_to_unix_file_name, wine_nt_to_unix_file_name,
unix_to_nt_file_name, wine_unix_to_nt_file_name,
set_show_dot_files, set_show_dot_files,
load_so_dll, load_so_dll,
load_builtin_dll, load_builtin_dll,

View File

@ -124,7 +124,6 @@ extern NTSTATUS CDECL exec_process( UNICODE_STRING *path, UNICODE_STRING *cmdlin
extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch, extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
CONTEXT *context ) DECLSPEC_HIDDEN; CONTEXT *context ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt ) DECLSPEC_HIDDEN;
extern void CDECL set_show_dot_files( BOOL enable ) DECLSPEC_HIDDEN; extern void CDECL set_show_dot_files( BOOL enable ) DECLSPEC_HIDDEN;
extern const char *home_dir DECLSPEC_HIDDEN; extern const char *home_dir DECLSPEC_HIDDEN;
@ -236,6 +235,7 @@ extern NTSTATUS tape_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTI
extern NTSTATUS errno_to_status( int err ) DECLSPEC_HIDDEN; extern NTSTATUS errno_to_status( int err ) DECLSPEC_HIDDEN;
extern NTSTATUS nt_to_unix_file_name( const UNICODE_STRING *nameW, char **name_ret, UINT disposition ) DECLSPEC_HIDDEN; extern NTSTATUS nt_to_unix_file_name( const UNICODE_STRING *nameW, char **name_ret, UINT disposition ) DECLSPEC_HIDDEN;
extern NTSTATUS unix_to_nt_file_name( const char *name, WCHAR **nt ) DECLSPEC_HIDDEN;
extern void init_files(void) DECLSPEC_HIDDEN; extern void init_files(void) DECLSPEC_HIDDEN;
extern void init_cpu_info(void) DECLSPEC_HIDDEN; extern void init_cpu_info(void) DECLSPEC_HIDDEN;