reg.exe - reg query implementation

MietekN namiltd at poczta.onet.pl
Thu Sep 13 03:33:54 CDT 2012


This is my patch for reg.exe which adds support for command "reg query".

Regards
-------------- next part --------------
diff -ruN programs.old/reg/reg.c programs/reg/reg.c
--- programs.old/reg/reg.c	2012-09-13 10:07:06.000000000 +0200
+++ programs/reg/reg.c	2012-09-13 10:29:58.000000000 +0200
@@ -1,5 +1,6 @@
 /*
  * Copyright 2008 Andrew Riedi
+ * Copyright 2012 Mieczyslaw Nalewaj
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -67,6 +68,22 @@
     return reg_printfW(formatW, msg_buffer);
 }
 
+static BOOL CompareRegW(LPCTSTR lpString1, LPCTSTR lpString2)
+{
+	int cchCount;
+	if ((!lpString1)||(!lpString2)||(!*lpString1)||(!*lpString2))
+	    return FALSE;
+	cchCount = strlenW(lpString2);
+	if (strlenW(lpString1)<cchCount)
+	    return FALSE;
+
+	if ( (CompareStringW(CP_ACP,NORM_IGNORECASE,lpString1,cchCount,lpString2,cchCount)==CSTR_EQUAL)
+    	    && ((lpString1[cchCount] == 0) || (lpString1[cchCount] == (WCHAR){'\\'}))) 
+	    return TRUE;
+	else
+	    return FALSE;
+}
+
 static HKEY get_rootkey(LPWSTR key)
 {
     static const WCHAR szHKLM[] = {'H','K','L','M',0};
@@ -80,20 +97,15 @@
     static const WCHAR szHKCC[] = {'H','K','C','C',0};
     static const WCHAR szHKEY_CURRENT_CONFIG[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','C','O','N','F','I','G',0};
 
-    if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,4,szHKLM,4)==CSTR_EQUAL ||
-        CompareStringW(CP_ACP,NORM_IGNORECASE,key,18,szHKEY_LOCAL_MACHINE,18)==CSTR_EQUAL)
+    if ( CompareRegW(key,szHKLM) || CompareRegW(key,szHKEY_LOCAL_MACHINE) )
         return HKEY_LOCAL_MACHINE;
-    else if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,4,szHKCU,4)==CSTR_EQUAL ||
-             CompareStringW(CP_ACP,NORM_IGNORECASE,key,17,szHKEY_CURRENT_USER,17)==CSTR_EQUAL)
+    else if ( CompareRegW(key,szHKCU) || CompareRegW(key,szHKEY_CURRENT_USER) )
         return HKEY_CURRENT_USER;
-    else if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,4,szHKCR,4)==CSTR_EQUAL ||
-             CompareStringW(CP_ACP,NORM_IGNORECASE,key,17,szHKEY_CLASSES_ROOT,17)==CSTR_EQUAL)
+    else if ( CompareRegW(key,szHKCR) || CompareRegW(key,szHKEY_CLASSES_ROOT) )
         return HKEY_CLASSES_ROOT;
-    else if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,3,szHKU,3)==CSTR_EQUAL ||
-             CompareStringW(CP_ACP,NORM_IGNORECASE,key,10,szHKEY_USERS,10)==CSTR_EQUAL)
+    else if ( CompareRegW(key,szHKU) || CompareRegW(key,szHKEY_USERS) )
         return HKEY_USERS;
-    else if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,4,szHKCC,4)==CSTR_EQUAL ||
-             CompareStringW(CP_ACP,NORM_IGNORECASE,key,19,szHKEY_CURRENT_CONFIG,19)==CSTR_EQUAL)
+    else if ( CompareRegW(key,szHKCC) || CompareRegW(key,szHKEY_CURRENT_CONFIG) )
         return HKEY_CURRENT_CONFIG;
     else return NULL;
 }
@@ -359,11 +371,157 @@
 static int reg_query(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
     BOOL subkey)
 {
-    static const WCHAR stubW[] = {'S','T','U','B',' ','Q','U','E','R','Y',' ',
-        '-',' ','%','s',' ','%','s',' ','%','d',' ','%','d','\n',0};
-    reg_printfW(stubW, key_name, value_name, value_empty, subkey);
+    LPWSTR p;
+    HKEY root, querykey;
+    DWORD count, dount, sount;
+
+    LPWSTR szValue;
+    LPBYTE bnData;
+    LPWSTR szSubk;
+
+    DWORD maxValue;
+    DWORD maxData;
+    DWORD maxSubk;
+
+    DWORD values;
+    DWORD type;
+    DWORD subkeys;
+    
+    LONG rc;
+    int licz;
+    int n;
+    WCHAR zaw;
+    BOOL exist = FALSE;
+    
+    static const WCHAR stubRW[] = {'\n', '!', ' ', 'R', 'E', 'G', '.', 'E', 'X', 'E',' ', 'V' ,'E', 'R', 'S', 'I', 'O', 'N', ' ', '1', '.', '0', '\n', '\n',0};
+
+    static const WCHAR stubW[] = {'%','s','\n',0};
+    static const WCHAR stubSW[] = {'%','s','\\','%','s','\n','\n',0};
+
+    static const WCHAR stubVALUEW[] = { '\t', '%', 's', '\t',0};
+    static const WCHAR stubVALUE0W[] = { '\t', '<', 'N', 'O', ' ', 'N', 'A', 'M', 'E', '>', '\t',0};
+    static const WCHAR stubREG_SZW[] = { 'R', 'E', 'G', '_', 'S', 'Z', '\t', '%', 's', '\n',0};
+    static const WCHAR stubREG_EXPAND_SZW[] = { 'R', 'E', 'G', '_', 'E', 'X', 'P', 'A', 'N', 'D', '_', 'S', 'Z', '\t', '%', 's', '\n',0};
+    static const WCHAR stubREG_DWORDW[] = { 'R', 'E', 'G', '_', 'D', 'W', 'O', 'R', 'D', '\t', '0', 'x', '%', 'X', '\n',0};
+    static const WCHAR stubREG_BINARY1W[] = { 'R', 'E', 'G', '_', 'D', 'W', 'O', 'R', 'D', '\t',0};
+    static const WCHAR stubREG_BINARY2W[] = { '%', '.','2', 'X' ,0};
+    static const WCHAR stubREG_MULTI_SZ1W[] = { 'R', 'E', 'G', '_', 'M', 'U', 'L', 'T', 'I', '_', 'S', 'Z', '\t',0};
+    static const WCHAR stubREG_MULTI_SZ2W[] = { '%', 'c' ,0};
+    static const WCHAR stubREG_MULTI_SZ0W[] = { '\\', '0' ,0};
+    static const WCHAR stubREG_3W[] = { '\n',0};
+
+
+    if (key_name[0]=='\\' && key_name[1]=='\\')
+    {
+        reg_message(STRING_NO_REMOTE);
+        return 1;
+    }
+
+    p = strchrW(key_name,'\\');
+    if (!p)
+    {
+        reg_message(STRING_INVALID_KEY);
+        return 1;
+    }
+    p++;
+
+    root = get_rootkey(key_name);
+    if (!root)
+    {
+        reg_message(STRING_INVALID_KEY);
+        return 1;
+    }
+
+    if(RegOpenKeyW(root,p,&querykey)!=ERROR_SUCCESS)
+    {
+        reg_message(STRING_CANNOT_FIND);
+        return 1;
+    }    
+
+    reg_printfW(stubRW);
 
-    return 1;
+    rc = RegQueryInfoKeyW(querykey, NULL, NULL, NULL, &subkeys, &maxSubk, NULL, &values,
+        &maxValue, &maxData, NULL, NULL);
+    if (rc != ERROR_SUCCESS)
+    {
+        RegCloseKey(querykey);
+        return 1;
+    }
+    maxValue++;
+    szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR));
+    maxData+=2;
+    bnData = HeapAlloc(GetProcessHeap(),0,maxData);
+    maxSubk++;
+    szSubk = HeapAlloc(GetProcessHeap(),0,maxSubk*sizeof(WCHAR));
+
+    reg_printfW(stubW, key_name);
+
+    rc = ERROR_SUCCESS;
+    for (licz=0; licz<values; licz++)
+    {
+        count = maxValue;
+        dount = maxData;
+        rc = RegEnumValueW(querykey, licz, szValue, &count, NULL, &type, bnData, &dount);
+	bnData[dount]=0;
+	bnData[dount+1]=0;
+	szValue[count]=0;
+        if (rc == ERROR_SUCCESS)
+        {
+    	    if ( ((!value_empty) && (!value_name)) ||
+		 ((value_empty)&&(count==0)) ||
+		 (!lstrcmpiW(szValue, value_name)) ) { 
+		exist = TRUE;
+        	if (count==0) reg_printfW(stubVALUE0W);
+		else reg_printfW(stubVALUEW, szValue);
+		
+		if (type==REG_SZ) reg_printfW(stubREG_SZW, bnData);
+		else if (type==REG_EXPAND_SZ) reg_printfW(stubREG_EXPAND_SZW, bnData);
+		else if (type==REG_DWORD) reg_printfW(stubREG_DWORDW, *bnData);
+		else if (type==REG_BINARY) {
+		    reg_printfW(stubREG_BINARY1W);
+		    for (n=0; n<dount; n++) 
+		        reg_printfW(stubREG_BINARY2W, bnData[n]);
+		    reg_printfW(stubREG_3W);
+		} else if (type==REG_MULTI_SZ) {
+		    reg_printfW(stubREG_MULTI_SZ1W);
+		    if (dount<=4) 
+		        reg_printfW(stubREG_MULTI_SZ0W);
+		    else for (n=0; n<dount; n+=2) { 
+		    	zaw = *((WCHAR*)(bnData+n));
+		    	if (zaw == 0)
+			    reg_printfW(stubREG_MULTI_SZ0W);
+			else
+			    reg_printfW(stubREG_MULTI_SZ2W, zaw);
+		    }
+		    reg_printfW(stubREG_3W);
+		}
+    	    }
+        }
+        else break;
+    }
+    reg_printfW(stubREG_3W);
+
+    if ((rc == ERROR_SUCCESS) && (!value_empty) && (!value_name)) for (licz=0; licz<subkeys; licz++)
+    {
+        sount = maxSubk;
+        rc = RegEnumKeyW(querykey, licz, szSubk, sount);
+        if (rc == ERROR_SUCCESS)
+        {
+    	    exist = TRUE;
+            reg_printfW(stubSW, key_name, szSubk);
+        }
+        else break;
+    }
+
+    RegCloseKey(querykey);
+
+    if (!exist)
+    {
+        reg_message(STRING_CANNOT_FIND);
+        return 1;
+    }
+
+    return 0;
 }
 
 int wmain(int argc, WCHAR *argvW[])


More information about the wine-patches mailing list