Commit 9674d849ebf for php.net

commit 9674d849ebf1c4841d278fc09023f9c2474cf758
Author: Gina Peter Banyard <girgias@php.net>
Date:   Thu Jul 16 17:04:15 2026 +0100

    main: convert win32_docref functions to a new function using new stream error API (#22748)

    * main: move php_win32_docref{1|2}_from_error() functions and make static

    Those are only used by the plain wrapper, so no need to expose them

    * main: convert win32_docref functions to a new fonction using new stream error API

diff --git a/ext/phar/tests/phar_buildfromdirectory2-win.phpt b/ext/phar/tests/phar_buildfromdirectory2-win.phpt
index 19a5ae8bfa2..e2d51b2c466 100644
--- a/ext/phar/tests/phar_buildfromdirectory2-win.phpt
+++ b/ext/phar/tests/phar_buildfromdirectory2-win.phpt
@@ -19,6 +19,6 @@
     echo $e->getMessage() . "\n";
 }
 ?>
---EXPECTF--
-%s(24) "UnexpectedValueException"
-RecursiveDirectoryIterator::__construct(1): %s (code: 2)
+--EXPECT--
+string(24) "UnexpectedValueException"
+RecursiveDirectoryIterator::__construct(1): Failed to open directory: No such file or directory
diff --git a/ext/phar/tests/phar_gobyebye-win32.phpt b/ext/phar/tests/phar_gobyebye-win32.phpt
index 7baa0c618fe..8100e6cf300 100644
--- a/ext/phar/tests/phar_gobyebye-win32.phpt
+++ b/ext/phar/tests/phar_gobyebye-win32.phpt
@@ -44,6 +44,4 @@
 bool(false)
 bool(false)

-Warning: opendir(foo/hi): %s (code: 3) in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d
-
 Warning: opendir(foo/hi): Failed to open directory: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d
diff --git a/ext/standard/tests/dir/bug80960.phpt b/ext/standard/tests/dir/bug80960.phpt
index 43d01465599..33fcaf9fe28 100644
--- a/ext/standard/tests/dir/bug80960.phpt
+++ b/ext/standard/tests/dir/bug80960.phpt
@@ -11,14 +11,8 @@
 opendir(str_pad("longname", PHP_MAXPATHLEN - strlen(getcwd()), "_"));
 ?>
 --EXPECTF--
-Warning: opendir(notexist*): %s (code: 123) in %s on line %d
-
 Warning: opendir(notexist*): Failed to open directory: No such file or directory in %s on line %d

-Warning: opendir(notexist?): %s (code: 123) in %s on line %d
-
 Warning: opendir(notexist?): Failed to open directory: No such file or directory in %s on line %d

-Warning: opendir(longname%r_+%r): %s (code: 111) in %s on line %d
-
 Warning: opendir(longname%r_+%r): Failed to open directory: Filename too long in %s on line %d
diff --git a/ext/standard/tests/dir/opendir_variation6-win32.phpt b/ext/standard/tests/dir/opendir_variation6-win32.phpt
index 40a0e919782..e2cd97f4e05 100644
--- a/ext/standard/tests/dir/opendir_variation6-win32.phpt
+++ b/ext/standard/tests/dir/opendir_variation6-win32.phpt
@@ -46,23 +46,15 @@
 -- Wildcard = '*' --

 Warning: opendir(%s/opendir_var*): %s in %s on line %d
-
-Warning: opendir(%s/opendir_var*): Failed to open directory: %s in %s on line %d
 bool(false)

 Warning: opendir(%s/*): %s in %s on line %d
-
-Warning: opendir(%s/*): Failed to open directory: %s in %s on line %d
 bool(false)

 -- Wildcard = '?' --

 Warning: opendir(%s/opendir_variation6/sub_dir?): %s in %s on line %d
-
-Warning: opendir(%s/opendir_variation6/sub_dir?): Failed to open directory: %s in %s on line %d
 bool(false)

-Warning: opendir(%s/opendir_variation6/sub?dir1): %s in %s on line %d
-
 Warning: opendir(%s/opendir_variation6/sub?dir1): Failed to open directory: %s in %s on line %d
 bool(false)
diff --git a/ext/standard/tests/file/rename_variation-win32.phpt b/ext/standard/tests/file/rename_variation-win32.phpt
index a348438bed5..158a8421ec7 100644
--- a/ext/standard/tests/file/rename_variation-win32.phpt
+++ b/ext/standard/tests/file/rename_variation-win32.phpt
@@ -61,7 +61,7 @@
 bool(true)
 -- Iteration 2 --

-Warning: rename(%s/rename_variation-win32/rename_variation.tmp/,%s/rename_variation2.tmp): %rThe filename, directory name, or volume label syntax is incorrect|The directory name is invalid%r (code: %r123|267%r) in %s on line %d
+Warning: rename(): %rThe filename, directory name, or volume label syntax is incorrect|The directory name is invalid%r (code: %r123|267%r) in %s on line %d
 bool(false)
 bool(false)
 bool(false)
diff --git a/ext/standard/tests/file/rename_variation11-win32.phpt b/ext/standard/tests/file/rename_variation11-win32.phpt
index e4c55fb6ce5..8b937b3db4e 100644
--- a/ext/standard/tests/file/rename_variation11-win32.phpt
+++ b/ext/standard/tests/file/rename_variation11-win32.phpt
@@ -86,12 +86,12 @@

 -- Iteration 5 --

-Warning: rename(%s\renameVar11\renameVar11Sub\..\\\renameVar11Sub\\..\\..\renameVar11Sub\renameMe.tmp,%s\renameVar11\renameVar11Sub\..\\\renameVar11Sub\\..\\..\renameVar11Sub\IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %s on line %d
 bool(false)

 -- Iteration 6 --

-Warning: rename(%s\renameVar11\renameVar11Sub\BADDIR\renameMe.tmp,%s\renameVar11\renameVar11Sub\BADDIR\IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %s on line %d
 bool(false)

 -- Iteration 7 --
@@ -112,7 +112,7 @@

 -- Iteration 11 --

-Warning: rename(BADDIR\renameMe.tmp,BADDIR\IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %s on line %d
 bool(false)

 -- Iteration 12 --
diff --git a/ext/standard/tests/file/rename_variation12-win32.phpt b/ext/standard/tests/file/rename_variation12-win32.phpt
index 527a8865c33..97aa58f6173 100644
--- a/ext/standard/tests/file/rename_variation12-win32.phpt
+++ b/ext/standard/tests/file/rename_variation12-win32.phpt
@@ -83,12 +83,12 @@

 -- Iteration 5 --

-Warning: rename(%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/renameMe.tmp,%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %s on line %d
 bool(false)

 -- Iteration 6 --

-Warning: rename(%s/renameVar12/renameVar12Sub/BADDIR/renameMe.tmp,%s/renameVar12/renameVar12Sub/BADDIR/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %s on line %d
 bool(false)

 -- Iteration 7 --
@@ -109,7 +109,7 @@

 -- Iteration 11 --

-Warning: rename(BADDIR/renameMe.tmp,BADDIR/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %s on line %d
 bool(false)

 *** Done ***
diff --git a/ext/standard/tests/file/rename_variation13-win32.phpt b/ext/standard/tests/file/rename_variation13-win32.phpt
index a2cf9a528d1..cfccdd87fc7 100644
--- a/ext/standard/tests/file/rename_variation13-win32.phpt
+++ b/ext/standard/tests/file/rename_variation13-win32.phpt
@@ -65,45 +65,45 @@
 -- 0 testing '-1' integer --
 bool(true)

-Warning: rename(-1,%safile.tmp): The system cannot find the file specified (code: 2) in %srename_variation13-win32.php on line %d
+Warning: rename(): The system cannot find the file specified (code: 2) in %srename_variation13-win32.php on line %d
 bool(false)
 -- 1 testing '1' boolean --
 bool(true)

-Warning: rename(1,%safile.tmp): The system cannot find the file specified (code: 2) in %srename_variation13-win32.php on line %d
+Warning: rename(): The system cannot find the file specified (code: 2) in %srename_variation13-win32.php on line %d
 bool(false)
 -- 2 testing '' boolean --

-Warning: rename(%safile.tmp,): %r(Invalid argument|(The parameter is incorrect|The system cannot find the path specified) \(code: \d+\))%r in %srename_variation13-win32.php on line %d
+Warning: rename(): %r(Invalid argument|(The parameter is incorrect|The system cannot find the path specified) \(code: \d+\))%r in %srename_variation13-win32.php on line %d
 bool(false)

-Warning: rename(,%safile.tmp): %r(Invalid argument|(The parameter is incorrect|The system cannot find the path specified) \(code: \d+\))%r in %srename_variation13-win32.php on line %d
+Warning: rename(): %r(Invalid argument|(The parameter is incorrect|The system cannot find the path specified) \(code: \d+\))%r in %srename_variation13-win32.php on line %d
 bool(false)
 -- 3 testing '' string --

-Warning: rename(%safile.tmp,): %r(Invalid argument|(The parameter is incorrect|The system cannot find the path specified) \(code: \d+\))%r in %srename_variation13-win32.php on line %d
+Warning: rename(): %r(Invalid argument|(The parameter is incorrect|The system cannot find the path specified) \(code: \d+\))%r in %srename_variation13-win32.php on line %d
 bool(false)

-Warning: rename(,%safile.tmp): %r(Invalid argument|(The parameter is incorrect|The system cannot find the path specified) \(code: \d+\))%r in %srename_variation13-win32.php on line %d
+Warning: rename(): %r(Invalid argument|(The parameter is incorrect|The system cannot find the path specified) \(code: \d+\))%r in %srename_variation13-win32.php on line %d
 bool(false)
 -- 4 testing ' ' string --

-Warning: rename(%s): The filename, directory name, or volume label syntax is incorrect (code: 123) in %srename_variation13-win32.php on line %d
+Warning: rename(): The filename, directory name, or volume label syntax is incorrect (code: 123) in %srename_variation13-win32.php on line %d
 bool(false)

-Warning: rename(%s): The filename, directory name, or volume label syntax is incorrect (code: 123) in %srename_variation13-win32.php on line %d
+Warning: rename(): The filename, directory name, or volume label syntax is incorrect (code: 123) in %srename_variation13-win32.php on line %d
 bool(false)
 -- 5 testing '/no/such/file/dir' string --

-Warning: rename(%safile.tmp,/no/such/file/dir): The system cannot find the path specified (code: 3) in %srename_variation13-win32.php on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %srename_variation13-win32.php on line %d
 bool(false)

-Warning: rename(/no/such/file/dir,%safile.tmp): The system cannot find the path specified (code: 3) in %srename_variation13-win32.php on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %srename_variation13-win32.php on line %d
 bool(false)
 -- 6 testing 'php/php' string --

-Warning: rename(%safile.tmp,php/php): The system cannot find the path specified (code: 3) in %srename_variation13-win32.php on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %srename_variation13-win32.php on line %d
 bool(false)

-Warning: rename(php/php,%safile.tmp): The system cannot find the path specified (code: 3) in %srename_variation13-win32.php on line %d
+Warning: rename(): The system cannot find the path specified (code: 3) in %srename_variation13-win32.php on line %d
 bool(false)
diff --git a/ext/standard/tests/file/rename_variation3-win32.phpt b/ext/standard/tests/file/rename_variation3-win32.phpt
index 8f347e5506f..84702711863 100644
--- a/ext/standard/tests/file/rename_variation3-win32.phpt
+++ b/ext/standard/tests/file/rename_variation3-win32.phpt
@@ -64,7 +64,7 @@

 -- Renaming existing file to existing directory name --

-Warning: rename(%s/rename_variation3.tmp,%s/rename_variation3_dir): Access is denied (code: 5) in %s on line %d
+Warning: rename(): Access is denied (code: 5) in %s on line %d
 bool(false)
 bool(true)
 bool(true)
diff --git a/ext/standard/tests/file/rename_variation8-win32.phpt b/ext/standard/tests/file/rename_variation8-win32.phpt
index c880cc60eeb..aa8c70ae51a 100644
--- a/ext/standard/tests/file/rename_variation8-win32.phpt
+++ b/ext/standard/tests/file/rename_variation8-win32.phpt
@@ -46,7 +46,7 @@
 --EXPECTF--
 *** Testing rename() on non-existing file ***

-Warning: rename(%s/non_existent_file.tmp,%s/rename_variation8_new.tmp): The system cannot find the file specified (code: 2) in %s on line %d
+Warning: rename(): The system cannot find the file specified (code: 2) in %s on line %d
 bool(false)
 bool(false)
 bool(false)
@@ -58,7 +58,7 @@

 *** Testing rename() on non-existing directory ***

-Warning: rename(%s/non_existent_dir,%s/rename_basic_dir2): The system cannot find the file specified (code: 2) in %s on line %d
+Warning: rename(): The system cannot find the file specified (code: 2) in %s on line %d
 bool(false)
 bool(false)
 bool(false)
diff --git a/ext/standard/tests/general_functions/bug44295-win.phpt b/ext/standard/tests/general_functions/bug44295-win.phpt
index e5eb4c26a94..fd014cf9e9a 100644
--- a/ext/standard/tests/general_functions/bug44295-win.phpt
+++ b/ext/standard/tests/general_functions/bug44295-win.phpt
@@ -23,7 +23,7 @@ function my_error_handler() {$a = func_get_args(); print "in error handler\n"; }
 ?>
 ==DONE==
 <?php exit(0); ?>
---EXPECTF--
+--EXPECT--
 before
-in catch: DirectoryIterator::__construct(c:\not\exists\here): %s (code: 3)
+in catch: DirectoryIterator::__construct(c:\not\exists\here): Failed to open directory: No such file or directory
 ==DONE==
diff --git a/main/main.c b/main/main.c
index 9e77c99a45d..aba833b43b9 100644
--- a/main/main.c
+++ b/main/main.c
@@ -1287,27 +1287,6 @@ PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1,
 }
 /* }}} */

-#ifdef PHP_WIN32
-PHPAPI ZEND_COLD void php_win32_docref1_from_error(DWORD error, const char *param1) {
-	char *buf = php_win32_error_to_msg(error);
-	size_t buf_len;
-
-	buf_len = strlen(buf);
-	if (buf_len >= 2) {
-		buf[buf_len - 1] = '\0';
-		buf[buf_len - 2] = '\0';
-	}
-	php_error_docref1(NULL, param1, E_WARNING, "%s (code: %lu)", buf, error);
-	php_win32_error_msg_free(buf);
-}
-
-PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2) {
-	char *buf = php_win32_error_to_msg(error);
-	php_error_docref2(NULL, param1, param2, E_WARNING, "%s (code: %lu)", buf, error);
-	php_win32_error_msg_free(buf);
-}
-#endif
-
 /* {{{ php_html_puts */
 PHPAPI void php_html_puts(const char *str, size_t size)
 {
diff --git a/main/php.h b/main/php.h
index 77976a68c01..c7516bca312 100644
--- a/main/php.h
+++ b/main/php.h
@@ -307,10 +307,6 @@ PHPAPI ZEND_COLD void php_error_docref1(const char *docref, const char *param1,
 	PHP_ATTRIBUTE_FORMAT(printf, 4, 5);
 PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format, ...)
 	PHP_ATTRIBUTE_FORMAT(printf, 5, 6);
-#ifdef PHP_WIN32
-PHPAPI ZEND_COLD void php_win32_docref1_from_error(DWORD error, const char *param1);
-PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2);
-#endif
 END_EXTERN_C()

 #define zenderror phperror
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index 9a98873b5d3..a95ca0eab76 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -161,6 +161,20 @@ typedef struct {
 } php_stdio_stream_data;
 #define PHP_STDIOP_GET_FD(anfd, data)	anfd = (data)->file ? fileno((data)->file) : (data)->fd

+#ifdef PHP_WIN32
+static ZEND_COLD void php_win32_stream_wrapper_warn_error(
+	php_stream_wrapper *wrapper,
+	php_stream_context *context,
+	int options,
+	zend_enum_StreamErrorCode code,
+	DWORD error
+) {
+	char *buf = php_win32_error_to_msg(error);
+	php_stream_wrapper_error(wrapper, context, NULL, options, E_WARNING, true, code, "%s (code: %lu)", buf, error);
+	php_win32_error_msg_free(buf);
+}
+#endif
+
 static int do_fstat(php_stdio_stream_data *d, int force)
 {
 	if (!d->cached_fstat || (force && !d->no_forced_fstat)) {
@@ -1130,7 +1144,7 @@ static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, const

 #ifdef PHP_WIN32
 	if (!dir) {
-		php_win32_docref1_from_error(GetLastError(), path);
+		php_win32_stream_wrapper_warn_error(wrapper, context, options, PHP_STREAM_EC(OpenFailed), GetLastError());
 	}

 	if (dir && dir->finished) {
@@ -1336,11 +1350,11 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f

 #ifdef PHP_WIN32
 	if (!php_win32_check_trailing_space(url_from, strlen(url_from))) {
-		php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to);
+		php_win32_stream_wrapper_warn_error(wrapper, context, options, PHP_STREAM_EC(InvalidPath), ERROR_INVALID_NAME);
 		return 0;
 	}
 	if (!php_win32_check_trailing_space(url_to, strlen(url_to))) {
-		php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to);
+		php_win32_stream_wrapper_warn_error(wrapper, context, options, PHP_STREAM_EC(InvalidPath), ERROR_INVALID_NAME);
 		return 0;
 	}
 #endif
@@ -1421,7 +1435,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f
 #endif

 #ifdef PHP_WIN32
-		php_win32_docref2_from_error(GetLastError(), url_from, url_to);
+		php_win32_stream_wrapper_warn_error(wrapper, context, options, PHP_STREAM_EC(RenameFailed), GetLastError());
 #else
 		php_stream_wrapper_warn(wrapper, context, options,
 				RenameFailed,