reg.exe - reg query implementation
Mieczyslaw Nalewaj
namiltd at poczta.onet.pl
Tue Sep 18 03:29:10 CDT 2012
This is a new version of my patch for reg.exe which adds support for
command "reg query".
P.S. The old version had the id 89851
-------------- next part --------------
diff --git a/programs/reg/reg.c b/programs/reg/reg.c
index 1b46661..8997235 100644
--- a/programs/reg/reg.c
+++ b/programs/reg/reg.c
@@ -1,5 +1,7 @@
/*
* Copyright 2008 Andrew Riedi
+ * Copyright 2010 Shuyin Lu
+ * 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
@@ -20,6 +22,10 @@
#include <wine/unicode.h>
#include "reg.h"
+#define MAX_KEY_LENGTH 256
+#define MAX_VALUE_NAME 16384
+#define MAX_TYPE_LENGTH 32
+
static int reg_printfW(const WCHAR *msg, ...)
{
va_list va_args;
@@ -67,6 +73,22 @@ static int reg_message(int msg)
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,24 +102,20 @@ static HKEY get_rootkey(LPWSTR key)
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;
}
+
static DWORD get_regtype(LPWSTR type)
{
static const WCHAR szREG_SZ[] = {'R','E','G','_','S','Z',0};
@@ -163,6 +181,316 @@ static LPBYTE get_regdata(LPWSTR data, DWORD reg_type, WCHAR separator, DWORD *r
return out_data;
}
+/*convert DWORD data type to string*/
+static void convert_type_to_wchar(WCHAR *type, const DWORD value_type)
+{
+ static const WCHAR szREG_SZ[] = {'R','E','G','_','S','Z',0};
+ static const WCHAR szREG_MULTI_SZ[] = {'R','E','G','_','M','U','L','T','I','_','S','Z',0};
+ static const WCHAR szREG_DWORD_BIG_ENDIAN[] = {'R','E','G','_','D','W','O','R','D','_','B','I','G','_','E','N','D','I','A','N',0};
+ static const WCHAR szREG_DWORD[] = {'R','E','G','_','D','W','O','R','D',0};
+ static const WCHAR szREG_BINARY[] = {'R','E','G','_','B','I','N','A','R','Y',0};
+ static const WCHAR szREG_DWORD_LITTLE_ENDIAN[] = {'R','E','G','_','D','W','O','R','D','_','L','I','T','T','L','E','_','E','N','D','I','A','N',0};
+ static const WCHAR szREG_NONE[] = {'R','E','G','_','N','O','N','E',0};
+ static const WCHAR szREG_EXPAND_SZ[] = {'R','E','G','_','E','X','P','A','N','D','_','S','Z',0};
+
+ if (value_type==REG_SZ)
+ lstrcpyW(type, szREG_SZ);
+ else if (value_type==REG_DWORD)
+ lstrcpyW(type, szREG_DWORD);
+ else if (value_type==REG_MULTI_SZ)
+ lstrcpyW(type, szREG_MULTI_SZ);
+ else if (value_type==REG_EXPAND_SZ)
+ lstrcpyW(type, szREG_EXPAND_SZ);
+ else if (value_type==REG_DWORD_BIG_ENDIAN)
+ lstrcpyW(type, szREG_DWORD_BIG_ENDIAN);
+ else if (value_type==REG_DWORD_LITTLE_ENDIAN)
+ lstrcpyW(type, szREG_DWORD_LITTLE_ENDIAN);
+ else if (value_type==REG_BINARY)
+ lstrcpyW(type, szREG_BINARY);
+ else if (value_type==REG_NONE)
+ lstrcpyW(type, szREG_NONE);
+}
+
+/*convert BYTE data to string*/
+static void convert_data_to_wchar(WCHAR *data_string, const BYTE *data_byte, const DWORD value_data_size, const DWORD value_type)
+{
+ DWORD i=0;
+ DWORD wchars_copied=0;
+ LPWSTR string_pointer;
+ WCHAR print_number[]={'%','0','2','X',0};
+ WCHAR print_numbershort[]={'%','X',0};
+ WCHAR print_wchar[]={'%','c',0};
+ WCHAR pre_dword[]={'0','x',0};
+ BOOL zero;
+
+ if (value_type==REG_SZ)
+ {
+ lstrcpyW(data_string, (LPCWSTR)data_byte);
+ }
+ else if (value_type==REG_DWORD)
+ {
+ lstrcpyW(data_string, pre_dword);
+ string_pointer = data_string + 2;
+ zero = TRUE;
+ for (i=0; i<value_data_size; i++)
+ {
+ wchars_copied=sprintfW(string_pointer, print_numbershort, data_byte[value_data_size-1-i]);
+ if ((zero) && (string_pointer[0]!='0'))
+ {
+ string_pointer+=wchars_copied;
+ }
+ else
+ {
+ zero = FALSE;
+ }
+ }
+ }
+ else if (value_type==REG_DWORD_BIG_ENDIAN)
+ {
+ lstrcpyW(data_string, pre_dword);
+ string_pointer=data_string+2;
+ for (i=0; i<value_data_size; i++)
+ {
+ wchars_copied=sprintfW(string_pointer, print_number, data_byte[i]);
+ string_pointer+=wchars_copied;
+ }
+ }
+ else if (value_type==REG_DWORD_LITTLE_ENDIAN)
+ {
+ lstrcpyW(data_string, pre_dword);
+ string_pointer=data_string+2;
+ for (i=0; i<value_data_size; i++)
+ {
+ wchars_copied=sprintfW(string_pointer, print_number, data_byte[value_data_size-1-i]);
+ string_pointer+=wchars_copied;
+ }
+ }
+ else if (value_type==REG_BINARY)
+ {
+ string_pointer=data_string;
+ for (i=0; i<value_data_size; i++)
+ {
+ wchars_copied=sprintfW(string_pointer, print_number, data_byte[i]);
+ string_pointer+=wchars_copied;
+ }
+ }
+ else if (value_type==REG_MULTI_SZ)
+ {
+ DWORD wchar_size=sizeof(WCHAR);
+ DWORD effective_data_size=value_data_size-2*wchar_size;
+ string_pointer=data_string;
+
+ if ((value_data_size>=2*wchar_size) && (effective_data_size>0)) for (i=0; i<=effective_data_size; i+=wchar_size)
+ {
+ if (data_byte[i]==0)
+ {
+ string_pointer[0]='\\';
+ string_pointer++;
+ string_pointer[0]='0';
+ string_pointer++;
+ }
+ else
+ {
+ wchars_copied=sprintfW(string_pointer, print_wchar, data_byte[i]);
+ if (wchars_copied==0)
+ string_pointer[0]=',';
+ string_pointer++;
+ }
+ }
+ string_pointer[0]='\\';
+ string_pointer++;
+ string_pointer[0]='0';
+ string_pointer++;
+ string_pointer[0]='\0';
+ }
+ else if (value_type==REG_EXPAND_SZ)
+ {
+ lstrcpyW(data_string, (LPCWSTR)data_byte);
+ }
+ else if (value_type==REG_NONE)
+ {
+ string_pointer=data_string;
+ for (i=0; i<value_data_size; i++)
+ {
+ wchars_copied=sprintfW(string_pointer, print_number, data_byte[i]);
+ string_pointer+=wchars_copied;
+ }
+ }
+}
+/*enumerate all values and subkeys under a key*/
+static DWORD enum_all_values_subkeys(HKEY hkey, WCHAR *key_name)
+{
+ LONG rc;
+ DWORD counter=0;
+ DWORD num_subkeys=0;
+ DWORD num_values=0;
+
+ WCHAR default_value_name[]={'(','D','e','f','a','u','l','t',')',0};
+ WCHAR value_name[MAX_VALUE_NAME];
+ DWORD value_name_length;
+
+ DWORD value_type;
+ WCHAR type[MAX_TYPE_LENGTH];
+
+ BYTE* value_data=NULL;
+ DWORD value_data_size;
+ DWORD max_data_size=256;
+ WCHAR *data=NULL;
+
+ WCHAR subkey_name[MAX_KEY_LENGTH];
+ DWORD subkey_length;
+
+ WCHAR print_keyname[]={'%','s','\n','\0'};
+// WCHAR print_value[]={' ',' ',' ',' ','%','s',' ',' ',' ',' ','%','s',' ',' ',' ',' ','%','s','\n','\0'};
+ WCHAR print_value[]={'\t','%','s','\t','%','s','\t','%','s','\n','\0'};
+ WCHAR print_subkey[]={'%','s','\\','%','s','\n','\0'};
+
+ rc = RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL,
+ &num_values, NULL, NULL, NULL, NULL);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ return 1;
+ }
+
+ reg_printfW(print_keyname, key_name);
+
+ value_data=HeapAlloc(GetProcessHeap(),0,max_data_size);
+ data=HeapAlloc(GetProcessHeap(),0,max_data_size*4);
+
+ /*enumerate values*/
+
+ for (counter=0; counter<num_values; counter++)
+ {
+ value_name_length = MAX_VALUE_NAME;
+ value_data_size = max_data_size;
+
+ rc = RegEnumValueW(hkey, counter, NULL, &value_name_length,
+ NULL, &value_type, NULL, &value_data_size);
+
+ if ((rc != ERROR_SUCCESS) || (value_name_length>MAX_VALUE_NAME))
+ {
+ HeapFree(GetProcessHeap(),0,value_data);
+ HeapFree(GetProcessHeap(),0,data);
+ return 1;
+ }
+
+ if (value_data_size>=max_data_size)
+ {
+ max_data_size=(value_data_size/256+1)*256;
+
+ value_data=HeapReAlloc(GetProcessHeap(),0,value_data,max_data_size);
+ data=HeapReAlloc(GetProcessHeap(),0,data,max_data_size*4);
+ }
+
+ rc = RegEnumValueW(hkey, counter, value_name, &value_name_length,
+ NULL, &value_type, value_data, &value_data_size);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(),0,value_data);
+ HeapFree(GetProcessHeap(),0,data);
+ return 1;
+ }
+
+ value_name[value_name_length]='\0';
+ if (value_name[0]=='\0')
+ lstrcpyW(value_name, default_value_name);
+ convert_type_to_wchar(type, value_type);
+ if (value_data_size>0)
+ {
+ convert_data_to_wchar(data, value_data, value_data_size, value_type);
+ }
+ else
+ {
+ data[0] = 0;
+ }
+
+ reg_printfW(print_value, value_name, type, data);
+ }
+
+ /*enumerate subkeys*/
+ for (counter=0; counter<num_subkeys; counter++)
+ {
+ subkey_length = MAX_KEY_LENGTH;
+
+ rc = RegEnumKeyExW(hkey, counter, subkey_name, &subkey_length,
+ NULL, NULL, NULL, NULL);
+
+ if ((rc != ERROR_SUCCESS) || (subkey_length>=MAX_KEY_LENGTH))
+ {
+ return 1;
+ }
+
+ subkey_name[subkey_length]='\0';
+ reg_printfW(print_subkey, key_name, subkey_name);
+ }
+
+ HeapFree(GetProcessHeap(),0,value_data);
+ HeapFree(GetProcessHeap(),0,data);
+ return 0;
+}
+
+static DWORD get_value_data(HKEY hkey, WCHAR *value_name)
+{
+ LONG rc;
+
+ DWORD value_type;
+ WCHAR type[MAX_TYPE_LENGTH];
+
+ BYTE* value_data=NULL;
+ DWORD value_data_size;
+ DWORD max_data_size=256;
+ WCHAR *data=NULL;
+
+ WCHAR default_value_name[]={'(','D','e','f','a','u','l','t',')',0};
+ WCHAR print_value[]={' ',' ',' ',' ','%','s',' ',' ',' ',' ','%','s',' ',' ',' ',' ','%','s','\n','\0'};
+
+ value_data=HeapAlloc(GetProcessHeap(),0,max_data_size);
+ data=HeapAlloc(GetProcessHeap(),0,max_data_size*4);
+
+ /*enumerate value*/
+ rc = RegGetValueW(hkey, NULL, value_name, RRF_RT_ANY, &value_type,
+ NULL, &value_data_size);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(),0,value_data);
+ HeapFree(GetProcessHeap(),0,data);
+ return 1;
+ }
+
+ if (value_data_size>=max_data_size)
+ {
+ max_data_size=(value_data_size/256+1)*256;
+
+ value_data=HeapReAlloc(GetProcessHeap(),0,value_data,max_data_size);
+ data=HeapReAlloc(GetProcessHeap(),0,data,max_data_size*4);
+ }
+
+ rc = RegGetValueW(hkey, NULL, value_name, RRF_RT_ANY, &value_type,
+ value_data, &value_data_size);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(),0,value_data);
+ HeapFree(GetProcessHeap(),0,data);
+ return 1;
+ }
+
+ convert_type_to_wchar(type, value_type);
+ convert_data_to_wchar(data, value_data, value_data_size, value_type);
+
+ if (value_name==NULL)
+ reg_printfW(print_value, default_value_name, type, data);
+ else
+ reg_printfW(print_value, value_name, type, data);
+
+ HeapFree(GetProcessHeap(),0,value_data);
+ HeapFree(GetProcessHeap(),0,data);
+ return 0;
+}
+
static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
WCHAR *type, WCHAR separator, WCHAR *data, BOOL force)
{
@@ -170,15 +498,23 @@ static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
' ','%','s',' ','%','d',' ','%','s',' ','%','s',' ','%','d','\n',0};
LPWSTR p;
HKEY root,subkey;
-
+ int klen;
+
reg_printfW(stubW, key_name, value_name, value_empty, type, data, force);
+
+ klen = strlenW(key_name);
- if (key_name[0]=='\\' && key_name[1]=='\\')
+ if ((klen < 2) || (key_name[0]=='\\' && key_name[1]=='\\'))
{
reg_message(STRING_NO_REMOTE);
return 1;
}
+ if (key_name[klen-1]=='\\')
+ {
+ key_name[klen-1] = 0;
+ }
+
p = strchrW(key_name,'\\');
if (!p)
{
@@ -240,18 +576,26 @@ static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
{
LPWSTR p;
HKEY root,subkey;
+ int klen;
static const WCHAR stubW[] = {'D','E','L','E','T','E',
' ','-',' ','%','s',' ','%','s',' ','%','d',' ','%','d',' ','%','d','\n'
,0};
reg_printfW(stubW, key_name, value_name, value_empty, value_all, force);
- if (key_name[0]=='\\' && key_name[1]=='\\')
+ klen = strlenW(key_name);
+
+ if ((klen < 2) || (key_name[0]=='\\' && key_name[1]=='\\'))
{
reg_message(STRING_NO_REMOTE);
return 1;
}
+ if (key_name[klen-1]=='\\')
+ {
+ key_name[klen-1] = 0;
+ }
+
p = strchrW(key_name,'\\');
if (!p)
{
@@ -359,11 +703,87 @@ static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
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,hkey;
+ int klen;
+
+ klen = strlenW(key_name);
+
+ if ((klen < 2) || (key_name[0]=='\\' && key_name[1]=='\\'))
+ {
+ reg_message(STRING_NO_REMOTE);
+ return 1;
+ }
- return 1;
+ if (key_name[klen-1]=='\\')
+ {
+ key_name[klen-1] = 0;
+ }
+
+ 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 (value_name && value_empty)
+ {
+ reg_message(STRING_INVALID_CMDLINE);
+ return 1;
+ }
+
+ if(RegOpenKeyW(root,p,&hkey)!=ERROR_SUCCESS)
+ {
+ reg_message(STRING_CANNOT_FIND);
+ return 1;
+ }
+
+ /* Output all subkeys and values if no /v or /ve option is given */
+ if (!value_name && !value_empty)
+ {
+ if (enum_all_values_subkeys(hkey, key_name)!=0)
+ {
+ /* FIXME: failure */
+ RegCloseKey(hkey);
+ reg_message(STRING_CANNOT_FIND);
+ return 1;
+ }
+ }
+ else if (value_name)
+ {
+ /* FIXME */
+ if (get_value_data(hkey, value_name)!=0)
+ {
+ /* FIXME: failure */
+ RegCloseKey(hkey);
+ reg_message(STRING_CANNOT_FIND);
+ return 1;
+ }
+ }
+ else if (value_empty)
+ {
+ /* FIXME */
+ if (get_value_data(hkey, value_name)!=0)
+ {
+ /* FIXME: failure */
+ RegCloseKey(hkey);
+ reg_message(STRING_CANNOT_FIND);
+ return 1;
+ }
+ }
+
+ RegCloseKey(hkey);
+
+ return 0;
}
int wmain(int argc, WCHAR *argvW[])
More information about the wine-patches
mailing list