[2/2] regedit: Deal with races in 'regedit /E' by resizing the buffers and retrying.

Francois Gouget fgouget at codeweavers.com
Sun Nov 23 14:02:03 CST 2008


---

If an application modifies a registry key (adds or modifies stuff) while 
we're exporting it, then we may get an ERROR_MORE_DATA error. Up to now 
this would either cause the export operation to be aborted (for values) 
or to try to recurse using the garbage in the buffer (for keys).

We cannot have a consistent result all the time in the presence of 
races. In particular, if an application deletes/adds values while we're 
exporting them, we may end up skipping some, or exporting the same value 
twice. But we cannot detect these issues anyway.

 programs/regedit/regproc.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c
index c1aee21..3e6cd94 100644
--- a/programs/regedit/regproc.c
+++ b/programs/regedit/regproc.c
@@ -1078,7 +1078,11 @@ static void export_hkey(FILE *file, HKEY key,
         DWORD val_size1 = *val_size;
         ret = RegEnumValueW(key, i, *val_name_buf, &val_name_size1, NULL,
                            &value_type, *val_buf, &val_size1);
-        if (ret != ERROR_SUCCESS) {
+        if (ret == ERROR_MORE_DATA) {
+            /* Increase the size of the buffers and retry */
+            REGPROC_resize_char_buffer(val_name_buf, val_name_size, val_name_size1);
+            REGPROC_resize_char_buffer(val_buf, val_size, val_size1);
+        } else if (ret != ERROR_SUCCESS) {
             more_data = FALSE;
             if (ret != ERROR_NO_MORE_ITEMS) {
                 REGPROC_print_error();
@@ -1169,7 +1173,10 @@ static void export_hkey(FILE *file, HKEY key,
 
         ret = RegEnumKeyExW(key, i, *reg_key_name_buf + curr_len + 1, &buf_size,
                            NULL, NULL, NULL, NULL);
-        if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA) {
+        if (ret == ERROR_MORE_DATA) {
+            /* Increase the size of the buffer and retry */
+            REGPROC_resize_char_buffer(reg_key_name_buf, reg_key_name_size, curr_len + 1 + buf_size);
+        } else if (ret != ERROR_SUCCESS) {
             more_data = FALSE;
             if (ret != ERROR_NO_MORE_ITEMS) {
                 REGPROC_print_error();
-- 
1.5.6.5




More information about the wine-patches mailing list