[PATCH 4/5] reg.exe: Add wchar/raw data conversion functions

Jonathan Vollebregt jnvsor at gmail.com
Mon Sep 1 08:05:33 CDT 2014


---
 programs/reg/reg.c | 111 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 91 insertions(+), 20 deletions(-)

diff --git a/programs/reg/reg.c b/programs/reg/reg.c
index dcf6a91..ad8582a 100644
--- a/programs/reg/reg.c
+++ b/programs/reg/reg.c
@@ -205,43 +205,114 @@ static DWORD wchar_get_type(LPWSTR type)
     return -1;
 }
 
-static LPBYTE get_regdata(LPWSTR data, DWORD reg_type, WCHAR separator, DWORD *reg_count)
+static LPWSTR data_get_wchar(const BYTE * data, const DWORD size, const DWORD type)
 {
-    LPBYTE out_data = NULL;
-    *reg_count = 0;
+    DWORD i=0;
+    LPWSTR input=NULL;
+    LPWSTR output=NULL;
+    WCHAR print_dwordW[]={'0','x','%','0','8','x',0};
+    WCHAR print_byteW[]={'%','0','2','x',0};
 
-    switch (reg_type)
+    switch(type)
     {
         case REG_SZ:
+        case REG_EXPAND_SZ:
         {
-            *reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR);
-            out_data = HeapAlloc(GetProcessHeap(),0,*reg_count);
-            lstrcpyW((LPWSTR)out_data,data);
+            output = HeapAlloc(GetProcessHeap(),0,size);
+
+            lstrcpyW(output, (LPCWSTR)data);
+            break;
+        }
+        case REG_DWORD:
+        case REG_DWORD_BIG_ENDIAN:
+        {
+            output = HeapAlloc(GetProcessHeap(),0,11 * sizeof(WCHAR));
+
+            i = * (DWORD *) data;
+            if (type==REG_DWORD_BIG_ENDIAN)
+            {
+                i = (i>>24) | ((i>>8)&0xFF00) | ((i&0xFF00)<<8) | (i<<24);
+            }
+            sprintfW(output, print_dwordW, i);
+            break;
+        }
+        case REG_MULTI_SZ:
+        {
+            output = HeapAlloc(GetProcessHeap(),0,size);
+
+            input = (LPWSTR) data;
+            while (input[i])
+            {
+                lstrcpyW(output+i, &input[i]);
+
+                i += strlenW(&input[i]) + 1;
+
+                if(input[i] != 0)
+                {
+                    output[i - 1] = ',';
+                }
+            }
+            break;
+        }
+        default:
+        {
+            output = HeapAlloc(GetProcessHeap(), 0, (size*2+1) * sizeof(WCHAR) );
+
+            for (i=0; i<size; i++)
+            {
+                sprintfW(output+i, print_byteW, data[i]);
+            }
+            break;
+        }
+    }
+    return output;
+}
+
+static LPBYTE wchar_get_data(const WCHAR * input, const DWORD type, WCHAR seperator, DWORD * size_out)
+{
+    LPBYTE output = NULL;
+    LPWSTR rest;
+    DWORD i;
+
+    static const WCHAR unhandled[] = {'U','n','h','a','n','d','l','e','d',' ','T','y','p','e',' ','%','s',' ',' ','d','a','t','a',' ','%','s','\n',0};
+    static const WCHAR nonnumber[] = {'E','r','r','o','r',':',' ','/','d',' ','r','e','q','u','i','r','e','s',' ','n','u','m','b','e','r','.','\n',0};
+
+    switch (type){
+        case REG_SZ:
+        case REG_EXPAND_SZ:
+        {
+            i = strlenW(input) * sizeof(WCHAR);
+            output = HeapAlloc(GetProcessHeap(),0,i);
+            lstrcpyW((LPWSTR) output,input);
+            *size_out = i;
             break;
         }
         case REG_DWORD:
+        case REG_DWORD_BIG_ENDIAN:
         {
-            LPWSTR rest;
-            DWORD val;
-            val = strtolW(data, &rest, 0);
-            if (rest == data) {
-                static const WCHAR nonnumber[] = {'E','r','r','o','r',':',' ','/','d',' ','r','e','q','u','i','r','e','s',' ','n','u','m','b','e','r','.','\n',0};
+            i = strtolW(input, &rest, 0);
+
+            if (rest == input) {
                 reg_printfW(nonnumber);
                 break;
             }
-            *reg_count = sizeof(DWORD);
-            out_data = HeapAlloc(GetProcessHeap(),0,*reg_count);
-            ((LPDWORD)out_data)[0] = val;
+
+            if (type==REG_DWORD_BIG_ENDIAN)
+            {
+                i = (i>>24) | ((i>>8)&0xFF00) | ((i&0xFF00)<<8) | (i<<24);
+            }
+
+            output = HeapAlloc(GetProcessHeap(),0,sizeof(DWORD));
+            *((LPDWORD)output) = i;
+            *size_out = sizeof(DWORD);
             break;
         }
         default:
         {
-            static const WCHAR unhandled[] = {'U','n','h','a','n','d','l','e','d',' ','T','y','p','e',' ','0','x','%','x',' ',' ','d','a','t','a',' ','%','s','\n',0};
-            reg_printfW(unhandled, reg_type,data);
+            reg_printfW(unhandled, type_get_wchar(type), input);
         }
     }
-
-    return out_data;
+    return output;
 }
 
 static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
@@ -277,7 +348,7 @@ static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
         }
 
         if (data)
-            reg_data = get_regdata(data,reg_type,separator,&reg_count);
+            reg_data = wchar_get_data(data,reg_type,separator,&reg_count);
 
         RegSetValueExW(key,value_name,0,reg_type,reg_data,reg_count);
         HeapFree(GetProcessHeap(),0,reg_data);
-- 
2.1.0




More information about the wine-patches mailing list