Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
a45ca342
Commit
a45ca342
authored
Nov 21, 2023
by
Eric Pouech
Committed by
Alexandre Julliard
Nov 21, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Lazily initialize ___winitenv.
parent
55b18b14
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
97 additions
and
99 deletions
+97
-99
data.c
dlls/msvcrt/data.c
+3
-77
environ.c
dlls/msvcrt/environ.c
+90
-15
msvcrt.h
dlls/msvcrt/msvcrt.h
+3
-2
environ.c
dlls/msvcrt/tests/environ.c
+0
-3
environ.c
dlls/ucrtbase/tests/environ.c
+1
-2
No files found.
dlls/msvcrt/data.c
View file @
a45ca342
...
...
@@ -60,77 +60,6 @@ int MSVCRT_app_type = 0;
char
*
MSVCRT__pgmptr
=
NULL
;
WCHAR
*
MSVCRT__wpgmptr
=
NULL
;
/* Get a snapshot of the current environment
* and construct the __p__environ array
*
* The pointer returned from GetEnvironmentStrings may get invalid when
* some other module cause a reallocation of the env-variable block
*
* blk is an array of pointers to environment strings, ending with a NULL
* and after that the actual copy of the environment strings, ending in a \0
*/
char
**
msvcrt_SnapshotOfEnvironmentA
(
char
**
blk
)
{
char
*
environ_strings
=
GetEnvironmentStringsA
();
int
count
=
1
,
len
=
1
,
i
=
0
;
/* keep space for the trailing NULLS */
char
*
ptr
;
for
(
ptr
=
environ_strings
;
*
ptr
;
ptr
+=
strlen
(
ptr
)
+
1
)
{
/* Don't count environment variables starting with '=' which are command shell specific */
if
(
*
ptr
!=
'='
)
count
++
;
len
+=
strlen
(
ptr
)
+
1
;
}
blk
=
realloc
(
blk
,
count
*
sizeof
(
char
*
)
+
len
);
if
(
blk
)
{
if
(
count
)
{
memcpy
(
&
blk
[
count
],
environ_strings
,
len
);
for
(
ptr
=
(
char
*
)
&
blk
[
count
];
*
ptr
;
ptr
+=
strlen
(
ptr
)
+
1
)
{
/* Skip special environment strings set by the command shell */
if
(
*
ptr
!=
'='
)
blk
[
i
++
]
=
ptr
;
}
}
blk
[
i
]
=
NULL
;
}
FreeEnvironmentStringsA
(
environ_strings
);
return
blk
;
}
wchar_t
**
msvcrt_SnapshotOfEnvironmentW
(
wchar_t
**
wblk
)
{
wchar_t
*
wenviron_strings
=
GetEnvironmentStringsW
();
int
count
=
1
,
len
=
1
,
i
=
0
;
/* keep space for the trailing NULLS */
wchar_t
*
wptr
;
for
(
wptr
=
wenviron_strings
;
*
wptr
;
wptr
+=
wcslen
(
wptr
)
+
1
)
{
/* Don't count environment variables starting with '=' which are command shell specific */
if
(
*
wptr
!=
'='
)
count
++
;
len
+=
wcslen
(
wptr
)
+
1
;
}
wblk
=
realloc
(
wblk
,
count
*
sizeof
(
wchar_t
*
)
+
len
*
sizeof
(
wchar_t
));
if
(
wblk
)
{
if
(
count
)
{
memcpy
(
&
wblk
[
count
],
wenviron_strings
,
len
*
sizeof
(
wchar_t
));
for
(
wptr
=
(
wchar_t
*
)
&
wblk
[
count
];
*
wptr
;
wptr
+=
wcslen
(
wptr
)
+
1
)
{
/* Skip special environment strings set by the command shell */
if
(
*
wptr
!=
'='
)
wblk
[
i
++
]
=
wptr
;
}
}
wblk
[
i
]
=
NULL
;
}
FreeEnvironmentStringsW
(
wenviron_strings
);
return
wblk
;
}
static
char
**
build_argv
(
WCHAR
**
wargv
)
{
int
argc
;
...
...
@@ -433,9 +362,7 @@ void msvcrt_init_args(void)
MSVCRT___unguarded_readlc_active
=
0
;
MSVCRT__fmode
=
_O_TEXT
;
MSVCRT__environ
=
msvcrt_SnapshotOfEnvironmentA
(
NULL
);
MSVCRT___initenv
=
msvcrt_SnapshotOfEnvironmentA
(
NULL
);
MSVCRT___winitenv
=
msvcrt_SnapshotOfEnvironmentW
(
NULL
);
env_init
(
FALSE
,
FALSE
);
MSVCRT__pgmptr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
MAX_PATH
);
if
(
MSVCRT__pgmptr
)
...
...
@@ -554,9 +481,8 @@ int CDECL __wgetmainargs(int *argc, wchar_t** *wargv, wchar_t** *wenvp,
MSVCRT___wargv
=
initial_wargv
;
}
/* Initialize the _wenviron array if it's not already created. */
if
(
!
MSVCRT__wenviron
)
MSVCRT__wenviron
=
msvcrt_SnapshotOfEnvironmentW
(
NULL
);
env_init
(
TRUE
,
FALSE
);
*
argc
=
MSVCRT___argc
;
*
wargv
=
MSVCRT___wargv
;
*
wenvp
=
MSVCRT__wenviron
;
...
...
dlls/msvcrt/environ.c
View file @
a45ca342
...
...
@@ -25,6 +25,83 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
msvcrt
);
int
env_init
(
BOOL
unicode
,
BOOL
modif
)
{
if
(
!
unicode
&&
(
!
MSVCRT___initenv
||
modif
))
{
char
*
environ_strings
=
GetEnvironmentStringsA
();
int
count
=
1
,
len
=
1
,
i
=
0
;
/* keep space for the trailing NULLS */
char
**
blk
,
*
ptr
;
for
(
ptr
=
environ_strings
;
*
ptr
;
ptr
+=
strlen
(
ptr
)
+
1
)
{
/* Don't count environment variables starting with '=' which are command shell specific */
if
(
*
ptr
!=
'='
)
count
++
;
len
+=
strlen
(
ptr
)
+
1
;
}
if
(
MSVCRT___initenv
!=
MSVCRT__environ
)
blk
=
realloc
(
MSVCRT__environ
,
count
*
sizeof
(
*
MSVCRT__environ
)
+
len
);
else
blk
=
malloc
(
count
*
sizeof
(
*
MSVCRT__environ
)
+
len
);
if
(
!
blk
)
{
FreeEnvironmentStringsA
(
environ_strings
);
return
-
1
;
}
MSVCRT__environ
=
blk
;
memcpy
(
&
MSVCRT__environ
[
count
],
environ_strings
,
len
);
for
(
ptr
=
(
char
*
)
&
MSVCRT__environ
[
count
];
*
ptr
;
ptr
+=
strlen
(
ptr
)
+
1
)
{
/* Skip special environment strings set by the command shell */
if
(
*
ptr
!=
'='
)
MSVCRT__environ
[
i
++
]
=
ptr
;
}
MSVCRT__environ
[
i
]
=
NULL
;
FreeEnvironmentStringsA
(
environ_strings
);
if
(
!
MSVCRT___initenv
)
MSVCRT___initenv
=
MSVCRT__environ
;
}
if
(
unicode
&&
(
!
MSVCRT___winitenv
||
modif
))
{
wchar_t
*
wenviron_strings
=
GetEnvironmentStringsW
();
int
count
=
1
,
len
=
1
,
i
=
0
;
/* keep space for the trailing NULLS */
wchar_t
**
wblk
,
*
wptr
;
for
(
wptr
=
wenviron_strings
;
*
wptr
;
wptr
+=
wcslen
(
wptr
)
+
1
)
{
/* Don't count environment variables starting with '=' which are command shell specific */
if
(
*
wptr
!=
'='
)
count
++
;
len
+=
wcslen
(
wptr
)
+
1
;
}
if
(
MSVCRT___winitenv
!=
MSVCRT__wenviron
)
wblk
=
realloc
(
MSVCRT__wenviron
,
count
*
sizeof
(
*
MSVCRT__wenviron
)
+
len
*
sizeof
(
wchar_t
));
else
wblk
=
malloc
(
count
*
sizeof
(
*
MSVCRT__wenviron
)
+
len
*
sizeof
(
wchar_t
));
if
(
!
wblk
)
{
FreeEnvironmentStringsW
(
wenviron_strings
);
return
-
1
;
}
MSVCRT__wenviron
=
wblk
;
memcpy
(
&
MSVCRT__wenviron
[
count
],
wenviron_strings
,
len
*
sizeof
(
wchar_t
));
for
(
wptr
=
(
wchar_t
*
)
&
MSVCRT__wenviron
[
count
];
*
wptr
;
wptr
+=
wcslen
(
wptr
)
+
1
)
{
/* Skip special environment strings set by the command shell */
if
(
*
wptr
!=
'='
)
MSVCRT__wenviron
[
i
++
]
=
wptr
;
}
MSVCRT__wenviron
[
i
]
=
NULL
;
FreeEnvironmentStringsW
(
wenviron_strings
);
if
(
!
MSVCRT___winitenv
)
MSVCRT___winitenv
=
MSVCRT__wenviron
;
}
return
0
;
}
static
int
env_get_index
(
const
char
*
name
)
{
int
i
,
len
;
...
...
@@ -77,10 +154,7 @@ static wchar_t * wgetenv_helper(const wchar_t *name)
int
idx
;
if
(
!
name
)
return
NULL
;
/* Initialize the _wenviron array if it's not already created. */
if
(
!
MSVCRT__wenviron
)
MSVCRT__wenviron
=
msvcrt_SnapshotOfEnvironmentW
(
NULL
);
if
(
env_init
(
TRUE
,
FALSE
))
return
NULL
;
idx
=
wenv_get_index
(
name
);
if
(
!
MSVCRT__wenviron
[
idx
])
return
NULL
;
...
...
@@ -133,10 +207,9 @@ int CDECL _putenv(const char *str)
/* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
if
((
ret
==
-
1
)
&&
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
ret
=
0
;
MSVCRT__environ
=
msvcrt_SnapshotOfEnvironmentA
(
MSVCRT__environ
);
if
(
ret
!=
-
1
)
ret
=
env_init
(
FALSE
,
TRUE
);
/* Update the __p__wenviron array only when already initialized */
if
(
MSVCRT__wenviron
)
MSVCRT__wenviron
=
msvcrt_SnapshotOfEnvironmentW
(
MSVCRT__wenviron
);
if
(
ret
!=
-
1
&&
MSVCRT__wenviron
)
ret
=
env_init
(
TRUE
,
TRUE
);
finish:
HeapFree
(
GetProcessHeap
(),
0
,
name
);
...
...
@@ -154,6 +227,8 @@ int CDECL _wputenv(const wchar_t *str)
TRACE
(
"%s
\n
"
,
debugstr_w
(
str
));
if
(
env_init
(
TRUE
,
FALSE
))
return
-
1
;
if
(
!
str
)
return
-
1
;
name
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
wcslen
(
str
)
+
1
)
*
sizeof
(
wchar_t
));
...
...
@@ -178,8 +253,8 @@ int CDECL _wputenv(const wchar_t *str)
/* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
if
((
ret
==
-
1
)
&&
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
ret
=
0
;
MSVCRT__environ
=
msvcrt_SnapshotOfEnvironmentA
(
MSVCRT__environ
);
MSVCRT__wenviron
=
msvcrt_SnapshotOfEnvironmentW
(
MSVCRT__wenviron
);
if
(
ret
!=
-
1
)
ret
=
env_init
(
FALSE
,
TRUE
);
if
(
ret
!=
-
1
)
ret
=
env_init
(
TRUE
,
TRUE
);
finish:
HeapFree
(
GetProcessHeap
(),
0
,
name
);
...
...
@@ -208,9 +283,8 @@ errno_t CDECL _putenv_s(const char *name, const char *value)
}
}
MSVCRT__environ
=
msvcrt_SnapshotOfEnvironmentA
(
MSVCRT__environ
);
MSVCRT__wenviron
=
msvcrt_SnapshotOfEnvironmentW
(
MSVCRT__wenviron
);
env_init
(
FALSE
,
TRUE
);
env_init
(
TRUE
,
TRUE
);
return
ret
;
}
...
...
@@ -223,6 +297,8 @@ errno_t CDECL _wputenv_s(const wchar_t *name, const wchar_t *value)
TRACE
(
"%s %s
\n
"
,
debugstr_w
(
name
),
debugstr_w
(
value
));
env_init
(
TRUE
,
FALSE
);
if
(
!
MSVCRT_CHECK_PMT
(
name
!=
NULL
))
return
EINVAL
;
if
(
!
MSVCRT_CHECK_PMT
(
value
!=
NULL
))
return
EINVAL
;
...
...
@@ -236,9 +312,8 @@ errno_t CDECL _wputenv_s(const wchar_t *name, const wchar_t *value)
}
}
MSVCRT__environ
=
msvcrt_SnapshotOfEnvironmentA
(
MSVCRT__environ
);
MSVCRT__wenviron
=
msvcrt_SnapshotOfEnvironmentW
(
MSVCRT__wenviron
);
env_init
(
FALSE
,
TRUE
);
env_init
(
TRUE
,
TRUE
);
return
ret
;
}
...
...
dlls/msvcrt/msvcrt.h
View file @
a45ca342
...
...
@@ -205,9 +205,10 @@ void __cdecl _amsg_exit(int errnum);
extern
char
**
MSVCRT__environ
;
extern
wchar_t
**
MSVCRT__wenviron
;
extern
char
**
MSVCRT___initenv
;
extern
wchar_t
**
MSVCRT___winitenv
;
extern
char
**
msvcrt_SnapshotOfEnvironmentA
(
char
**
);
extern
wchar_t
**
msvcrt_SnapshotOfEnvironmentW
(
wchar_t
**
);
int
env_init
(
BOOL
,
BOOL
);
wchar_t
*
msvcrt_wstrdupa
(
const
char
*
);
...
...
dlls/msvcrt/tests/environ.c
View file @
a45ca342
...
...
@@ -139,7 +139,6 @@ static void test__environ(void)
{
initenv
=
*
p__p___initenv
();
todo_wine
ok
(
initenv
==
*
p_environ
,
"Expected _environ to be equal to initial env
\n
"
);
}
...
...
@@ -195,7 +194,6 @@ static void test__wenviron(void)
if
(
p__p___winitenv
)
{
wchar_t
***
retptr
=
p__p___winitenv
();
todo_wine
ok
(
!*
retptr
,
"Expected initial env to be NULL
\n
"
);
}
else
...
...
@@ -235,7 +233,6 @@ static void test__wenviron(void)
"Expected _wenviron to be different from __p___winitenv() %p %p
\n
"
,
*
retptr
,
*
p_wenviron
);
/* test that w-initial env is derived from current _environ[] and not from ansi initial env */
value
=
env_get_valueW
(
*
retptr
,
L"cat"
);
todo_wine
ok
(
value
&&
!
wcscmp
(
value
,
L"dog"
),
"Expecting initial env to be derived from current env (got %ls)
\n
"
,
value
);
}
...
...
dlls/ucrtbase/tests/environ.c
View file @
a45ca342
...
...
@@ -132,13 +132,12 @@ static void test_initial_environ( void )
ok
(
p__p__environ
()
!=
NULL
,
"Unexpected NULL _environ[]
\n
"
);
ok
(
*
p__p__environ
()
!=
NULL
,
"Unexpected empty _environ[]
\n
"
);
ok
(
p_get_initial_narrow_environment
()
!=
NULL
,
"Unexpected empty narrow initial environment
\n
"
);
todo_wine
ok
(
p_get_initial_narrow_environment
()
==
*
p__p__environ
(),
"Expecting _environ[] to match initial narrow environment
\n
"
);
ok
(
p__p__wenviron
()
!=
NULL
,
"Unexpected NULL _wenviron[]
\n
"
);
ok
(
*
p__p__wenviron
()
==
NULL
,
"Unexpected non empty _wenviron[]
\n
"
);
ok
(
p_get_initial_wide_environment
()
!=
NULL
,
"Unexpected empty wide initial environment
\n
"
);
todo_wine
ok
(
p_get_initial_wide_environment
()
!=
NULL
,
"Unexpected empty wide initial environment
\n
"
);
ok
(
p_get_initial_wide_environment
()
==
*
p__p__wenviron
(),
"Expecting _wenviron[] to match initial wide environment
\n
"
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment