The previous patch was created from wrong directory and it contains errors
that prohibited it from compiling.
Disadvantage of working with multiple screens, where I thought I was working
in same directory.
Attached to this email you will find the patch that does not break the
compilation :) I have tested this within the same screen, make clean ; make ;
make install and then ran the dump test again. I can assure, it works now :)
Furthermore, to answer the question of David, Yes, that function still
works :) (Just for being sure, ran a test on this one also). Besides that,
this function does not appear to be used a lot.
I am really sorry for all the trouble..
Guido Diepen
--
Aviation is proof that given the will, we have the
capacity to achieve the impossible.
--Eddie Rickenbacker
Index: src/rapi2.c
===================================================================
--- src/rapi2.c (revision 3074)
+++ src/rapi2.c (working copy)
@@ -68,9 +68,9 @@
_CeRegCloseKey2, /* CeRegCloseKey */
_CeRegDeleteKey2, /* CeRegDeleteKey */
_CeRegDeleteValue2, /* CeRegDeleteValue */
- NULL, /* CeRegQueryInfoKey */
+ _CeRegQueryInfoKey2, /* CeRegQueryInfoKey */
_CeRegQueryValueEx2, /* CeRegQueryValueEx */
- NULL, /* CeRegEnumValue */
+ _CeRegEnumValue2, /* CeRegEnumValue */
_CeRegEnumKeyEx2, /* CeRegEnumKeyEx */
_CeRegSetValueEx2, /* CeRegSetValueEx */
#endif /* SWIG */
Index: src/support/rapi_buffer.c
===================================================================
--- src/support/rapi_buffer.c (revision 3074)
+++ src/support/rapi_buffer.c (working copy)
@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <stdio.h>
#if HAVE_SYS_UIO_H
/* For readv/writev */
@@ -434,12 +435,13 @@
*size = exact_size;
- if ( !rapi_buffer_read_data(buffer, unicode, (exact_size+1) * sizeof(WCHAR)) )
+ if ( !rapi_buffer_read_data(buffer, unicode, (exact_size) * sizeof(WCHAR)) )
{
rapi_buffer_error("failed to read buffer");
return false;
}
-
+ //Ensure that last character is 0 terminator!!!
+ unicode[exact_size] = 0 ;
return true;
}
@@ -648,6 +650,82 @@
return false;
}
+
+
+
+void rapi_buffer_dump_buffer_from_current_point( char* desc, RapiBuffer* buffer)
+{
+ uint8_t* buf = (uint8_t*)buffer->data;
+ size_t len = buffer->bytes_used ;
+ size_t i, j;
+ char hex[8 * 3 + 1];
+ char chr[8 + 1];
+
+
+ printf("%s (%d remaining bytes):\n", desc, len);
+ for (i = buffer->read_index ; i < len + 7; i += 8) {
+ for (j = 0; j < 8; j++)
+ if (j + i >= len) {
+ hex[3*j+0] = ' ';
+ hex[3*j+1] = ' ';
+ hex[3*j+2] = ' ';
+ chr[j] = ' ';
+ } else {
+ uint8_t c = buf[j + i];
+ const char *hexchr = "0123456789abcdef";
+ hex[3*j+0] = hexchr[(c >> 4) & 0xf];
+ hex[3*j+1] = hexchr[c & 0xf];
+ hex[3*j+2] = ' ';
+ if (c > ' ' && c <= '~')
+ chr[j] = c;
+ else
+ chr[j] = '.';
+ }
+ hex[8*3] = '\0';
+ chr[8] = '\0';
+ printf(" %04x: %s %s\n", i, hex, chr);
+ }
+}
+
+
+
+
+
+void rapi_buffer_debug_dump_buffer( char* desc, RapiBuffer* buffer)
+{
+ uint8_t* buf = (uint8_t*)buffer->data;
+ size_t len = buffer->bytes_used ;
+ size_t i, j;
+ char hex[8 * 3 + 1];
+ char chr[8 + 1];
+
+ printf("%s (%d bytes):\n", desc, len);
+ for (i = 0; i < len + 7; i += 8) {
+ for (j = 0; j < 8; j++)
+ if (j + i >= len) {
+ hex[3*j+0] = ' ';
+ hex[3*j+1] = ' ';
+ hex[3*j+2] = ' ';
+ chr[j] = ' ';
+ } else {
+ uint8_t c = buf[j + i];
+ const char *hexchr = "0123456789abcdef";
+ hex[3*j+0] = hexchr[(c >> 4) & 0xf];
+ hex[3*j+1] = hexchr[c & 0xf];
+ hex[3*j+2] = ' ';
+ if (c > ' ' && c <= '~')
+ chr[j] = c;
+ else
+ chr[j] = '.';
+ }
+ hex[8*3] = '\0';
+ chr[8] = '\0';
+ printf(" %04x: %s %s\n", i, hex, chr);
+ }
+}
+
+
+
bool rapi_buffer_read_find_data(
RapiBuffer* buffer,
LPCE_FIND_DATA lpFindFileData)
Index: src/support/rapi_buffer.h
===================================================================
--- src/support/rapi_buffer.h (revision 3074)
+++ src/support/rapi_buffer.h (working copy)
@@ -158,5 +158,22 @@
RapiBuffer* buffer,
LPCE_FIND_DATA lpFindFileData);
+
+/**
+ * Dump the complete buffer that is supplied as parameter
+ */
+void rapi_buffer_dump_buffer(
+ char* desc,
+ RapiBuffer* buffer) ;
+
+/**
+ * Dump the remainder of the buffer that is supplied as
+ * a parameter. Mostly of use when dumping the recv buffer
+ */
+void rapi_buffer_dump_buffer_from_current_point(
+ char* desc,
+ RapiBuffer* buffer) ;
+
+
#endif
Index: src/rapi2/registry2.c
===================================================================
--- src/rapi2/registry2.c (revision 3074)
+++ src/rapi2/registry2.c (working copy)
@@ -2,7 +2,9 @@
#include "rapi2_api.h"
#include "rapi_context.h"
#include <stdlib.h>
+#include <stdio.h>
+
LONG _CeRegCreateKeyEx2(
HKEY hKey,
LPCWSTR lpszSubKey,
@@ -193,7 +195,7 @@
}
-/*
+
LONG _CeRegQueryInfoKey2(
HKEY hKey,
LPWSTR lpClass,
@@ -211,44 +213,59 @@
RapiContext* context = rapi_context_current();
LONG return_value = ERROR_GEN_FAILURE;
- rapi_context_begin_command(context, 0x25);
- rapi_buffer_write_uint32 (context->send_buffer, hKey);
- rapi_buffer_write_optional (context->send_buffer, lpClass, lpcbClass ? *lpcbClass * sizeof(WCHAR) : 0, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcbClass, true);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpReserved, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcSubKeys, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcbMaxSubKeyLen, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcbMaxClassLen, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcValues, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcbMaxValueNameLen, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcbMaxValueLen, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcbSecurityDescriptor, false);
- rapi_buffer_write_optional (context->send_buffer, lpftLastWriteTime, sizeof(FILETIME), false);
+ rapi_context_begin_command(context, 0x36);
+ rapi_buffer_write_uint32 (context->send_buffer, hKey);
+ rapi_buffer_write_uint32 (context->send_buffer, lpcbClass ? *lpcbClass : 0 );
+ //lpftLastWriteTime, this should be put to 0
+ rapi_buffer_write_uint32 (context->send_buffer, 0 );
+
+
if ( !rapi2_context_call(context) )
return ERROR_GEN_FAILURE;
rapi_buffer_read_uint32(context->recv_buffer, &context->last_error);
rapi_buffer_read_int32(context->recv_buffer, &return_value);
+
+
if (ERROR_SUCCESS == return_value)
{
- rapi_buffer_read_optional (context->recv_buffer, lpClass, lpcbClass ? *lpcbClass * sizeof(WCHAR) : 0);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcbClass);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpReserved);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcSubKeys);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcbMaxSubKeyLen);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcbMaxClassLen);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcValues);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcbMaxValueNameLen);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcbMaxValueLen);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcbSecurityDescriptor);
- rapi_buffer_read_optional_filetime(context->recv_buffer, lpftLastWriteTime);
+ DWORD foo = 0 ;
+
+ rapi_buffer_read_uint32 (context->recv_buffer, &foo ) ;
+ if (lpClass)
+ {
+ *lpcbClass = foo ;
+ rapi_buffer_read_string(context->recv_buffer, lpClass, lpcbClass );
+
+ }
+
+
+ rapi_buffer_read_uint32 (context->recv_buffer, &foo ) ;
+ if (lpcSubKeys)
+ *lpcSubKeys = foo ;
+ rapi_buffer_read_uint32 (context->recv_buffer, &foo ) ;
+ if (lpcbMaxSubKeyLen)
+ *lpcbMaxSubKeyLen = foo ;
+ rapi_buffer_read_uint32 (context->recv_buffer, &foo ) ;
+ if (lpcbMaxClassLen)
+ *lpcbMaxClassLen = foo ;
+ rapi_buffer_read_uint32 (context->recv_buffer, &foo ) ;
+ if (lpcValues)
+ *lpcValues = foo ;
+ rapi_buffer_read_uint32 (context->recv_buffer, &foo ) ;
+ if (lpcbMaxValueNameLen)
+ *lpcbMaxValueNameLen = foo ;
+ rapi_buffer_read_uint32 (context->recv_buffer, &foo ) ;
+ if (lpcbMaxValueLen)
+ *lpcbMaxValueLen = foo ;
}
return return_value;
}
+
LONG _CeRegEnumValue2(
HKEY hKey,
DWORD dwIndex,
@@ -262,36 +279,57 @@
RapiContext* context = rapi_context_current();
LONG return_value = ERROR_GEN_FAILURE;
- rapi_context_begin_command(context, 0x23);
+ rapi_context_begin_command(context, 0x34);
rapi_buffer_write_uint32 (context->send_buffer, hKey);
rapi_buffer_write_uint32 (context->send_buffer, dwIndex);
- rapi_buffer_write_optional (context->send_buffer, lpszValueName, lpcbValueName ? *lpcbValueName * sizeof(WCHAR) : 0, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcbValueName, true);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpReserved, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpType, false);
- rapi_buffer_write_optional (context->send_buffer, lpData, lpcbData ? *lpcbData : 0, false);
- rapi_buffer_write_optional_uint32(context->send_buffer, lpcbData, true);
+ //What is the size of the buffer we have for ValueName
+ rapi_buffer_write_uint32(context->send_buffer, *lpcbValueName);
+ //What is the size of the buffer we have for the data
+ rapi_buffer_write_uint32(context->send_buffer, *lpcbData );
+
+
if ( !rapi2_context_call(context) )
return false;
+
+
rapi_buffer_read_uint32(context->recv_buffer, &context->last_error);
rapi_buffer_read_int32(context->recv_buffer, &return_value);
+
+
if (ERROR_SUCCESS == return_value)
{
- rapi_buffer_read_optional (context->recv_buffer, lpszValueName, lpcbValueName ? *lpcbValueName * sizeof(WCHAR) : 0);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcbValueName);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpReserved);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpType);
- rapi_buffer_read_optional (context->recv_buffer, lpData, lpcbData ? *lpcbData : 0);
- rapi_buffer_read_optional_uint32(context->recv_buffer, lpcbData);
+ DWORD foo ;
+
+ //First read the valuename
+ rapi_buffer_read_string(context->recv_buffer, lpszValueName, lpcbValueName ) ;
+
+ //Then read the type
+ foo = 0 ;
+ rapi_buffer_read_uint32(context->recv_buffer, &foo );
+ if (lpType)
+ *lpType = foo ;
+
+
+ //Then read the data if needed
+ rapi_buffer_read_uint32(context->recv_buffer, &foo );
+ if (lpData) {
+ *lpcbData = foo ;
+
+ if (REG_DWORD == *lpType) {
+ rapi_buffer_read_uint32(context->recv_buffer, (uint32_t *) lpData);
+ } else {
+ rapi_buffer_read_data(context->recv_buffer, lpData, *lpcbData);
+ }
+ }
}
return return_value;
}
-*/
+
LONG _CeRegEnumKeyEx2(
HKEY hKey,
DWORD dwIndex,
@@ -310,7 +348,7 @@
rapi_buffer_write_uint32 (context->send_buffer, dwIndex);
rapi_buffer_write_uint32(context->send_buffer, *lpcbName);
- rapi_buffer_write_uint32(context->send_buffer, 0);
+ rapi_buffer_write_uint32(context->send_buffer, lpcbClass ? *lpcbClass : 0 );
rapi_buffer_write_uint32(context->send_buffer, 0);
@@ -322,7 +360,14 @@
if (ERROR_SUCCESS == return_value)
{
- rapi_buffer_read_string(context->recv_buffer, lpName, lpcbName );
+ if (lpName)
+ {
+ rapi_buffer_read_string(context->recv_buffer, lpName, lpcbName );
+ }
+ if (lpClass)
+ {
+ rapi_buffer_read_string(context->recv_buffer, lpClass, lpcbClass );
+ }
}
return return_value;
Index: src/rapi2/rapi2_api.h
===================================================================
--- src/rapi2/rapi2_api.h (revision 3074)
+++ src/rapi2/rapi2_api.h (working copy)
@@ -87,6 +87,21 @@
LPCWSTR lpNewFileName,
BOOL bFailIfExists);
+
+LONG _CeRegQueryInfoKey2(
+ HKEY hKey,
+ LPWSTR lpClass,
+ LPDWORD lpcbClass,
+ LPDWORD lpReserved,
+ LPDWORD lpcSubKeys,
+ LPDWORD lpcbMaxSubKeyLen,
+ LPDWORD lpcbMaxClassLen,
+ LPDWORD lpcValues,
+ LPDWORD lpcbMaxValueNameLen,
+ LPDWORD lpcbMaxValueLen,
+ LPDWORD lpcbSecurityDescriptor,
+ PFILETIME lpftLastWriteTime);
+
BOOL _CeCopyFileA2(
LPCSTR lpExistingFileName,
LPCSTR lpNewFileName,
@@ -144,6 +159,16 @@
REGSAM samDesired,
PHKEY phkResult);
+LONG _CeRegEnumValue2(
+ HKEY hKey,
+ DWORD dwIndex,
+ LPWSTR lpszValueName,
+ LPDWORD lpcbValueName,
+ LPDWORD lpReserved,
+ LPDWORD lpType,
+ LPBYTE lpData,
+ LPDWORD lpcbData);
+
LONG _CeRegEnumKeyEx2(
HKEY hKey,
DWORD dwIndex,
Index: tools/synce-registry.c
===================================================================
--- tools/synce-registry.c (revision 3074)
+++ tools/synce-registry.c (working copy)
@@ -13,14 +13,20 @@
#define ACTION_LISTKEY 3
#define ACTION_NEWKEY 4
#define ACTION_DELETEKEY 5
+#define ACTION_DUMP_REGISTRY 6
+
char* devname = NULL;
int action = ACTION_READVAL;
+bool list_recurse = false ;
DWORD valType = REG_SZ;
const char *prog_name;
#define STR_EQUAL(a,b) (0 == strcasecmp(a,b))
+int read_val(char *parent_str, char *key_str, HKEY key, LPCWSTR value_name_wide) ;
+
+
static void show_usage(const char* name)
{
fprintf(stderr,
@@ -39,6 +45,8 @@
"\t 1 - Errors only\n"
"\t 2 - Errors and warnings\n"
"\t 3 - Everything\n"
+ "\t-D Dump complete registry to screen\n"
+ "\t-L Enable list recursion\n"
"\t-h Show this help message\n"
"\t-p DEVNAME Mobile device name\n"
"\t-t TYPE New type for writes:\n"
@@ -94,7 +102,7 @@
{
int c;
int log_level = SYNCE_LOG_LEVEL_LOWEST;
- while ((c = getopt(argc, argv, "d:hp:t:rwxlnX")) != -1)
+ while ((c = getopt(argc, argv, "d:hp:t:rwxlnXDL")) != -1)
{
switch (c)
{
@@ -102,6 +110,9 @@
log_level = atoi(optarg);
break;
+ case 'L':
+ list_recurse = true ;
+ break ;
case 'p':
devname = optarg;
break;
@@ -130,7 +141,11 @@
action = ACTION_DELETEKEY;
break;
- case 't':
+ case 'D':
+ action = ACTION_DUMP_REGISTRY;
+ break;
+
+ case 't':
if (strcasecmp(optarg,"binary") == 0)
{
valType = REG_BINARY;
@@ -275,18 +290,58 @@
return 0;
}
-int list_key(HKEY key)
-{
+
+int list_key(HKEY key, char* key_path, bool do_recurse)
+{
+ //First print the path till now:
+ printf("\n[%s]\n", key_path );
+
+
int result;
int i;
+
+ //First determine the size of the holding arrays for all
+ //subvalues/keys
+ DWORD lpcSubKeys ;
+ DWORD lpcbMaxSubKeyLen ;
+ DWORD lpcbMaxClassLen ;
+ DWORD lpcValues ;
+ DWORD lpcbMaxValueNameLen ;
+ DWORD lpcbMaxValueLen ;
+
+ result = CeRegQueryInfoKey(key, NULL, NULL, NULL,
+ &lpcSubKeys, &lpcbMaxSubKeyLen, &lpcbMaxClassLen,
+ &lpcValues, &lpcbMaxValueNameLen, &lpcbMaxValueLen,
+ NULL, NULL) ;
+
+ //One important thing is to add +1 to all string lengths, since we need to
+ //add the zero-terminator also, which is not present in the device.
+
+ lpcbMaxClassLen++ ;
+ lpcbMaxValueNameLen++ ;
+ lpcbMaxValueLen++ ;
+ lpcbMaxSubKeyLen++ ;
+
+
+
+ //First print all of the values
for(i = 0; ; i++)
{
- WCHAR wide_name[MAX_PATH];
- DWORD name_size = sizeof(wide_name);
-
- result = CeRegEnumKeyEx(key, i, wide_name, &name_size, NULL, NULL,
- NULL, NULL);
+ DWORD value_name_wide_size = lpcbMaxValueNameLen ;
+ WCHAR value_name_wide[value_name_wide_size];
+
+ DWORD value_size = lpcbMaxValueLen ;
+ uint8_t value[value_size];
+
+ DWORD value_type;
+
+
+
+ result = CeRegEnumValue(key, i, value_name_wide ,
+ &value_name_wide_size, NULL, &value_type,
+ value , &value_size );
+
if (ERROR_NO_MORE_ITEMS == result)
break;
else if (ERROR_SUCCESS != result)
@@ -296,16 +351,33 @@
synce_strerror(result));
return 1;
}
- printf("K %s\n",wstr_to_ascii(wide_name));
+
+ printf("\"%s\"=", wstr_to_ascii(value_name_wide));
+
+ switch (value_type)
+ {
+ case REG_SZ:
+ printf("\"%s\"\n", wstr_to_ascii((LPCWSTR)value));
+ break;
+
+ case REG_DWORD:
+ printf("dword=%08x\n", *(DWORD*)value);
+ break;
+
+ default:
+ dump("Value", value, value_size);
+ break;
+ }
}
+
for(i = 0; ; i++)
{
+
WCHAR wide_name[MAX_PATH];
DWORD name_size = sizeof(wide_name);
- DWORD type;
- result = CeRegEnumValue(key, i, wide_name, &name_size, NULL, &type,
+ result = CeRegEnumKeyEx(key, i, wide_name, &name_size, NULL, NULL,
NULL, NULL);
if (ERROR_NO_MORE_ITEMS == result)
break;
@@ -316,15 +388,81 @@
synce_strerror(result));
return 1;
}
- /* TODO: We already have the value type, might as well display it. */
- /* TODO: We have the value itself, too, so maybe just display that. */
- /* TODO: It's probably pretty easy to make this work recursively, while we're at it */
- /* TODO: Which would be a pretty good registry dump tool. */
- printf("V %s\n",wstr_to_ascii(wide_name));
+
+
+ if (!do_recurse){
+ //Then just print all the subkeys
+ printf("\n") ;
+ fprintf(stdout, "[%s\\%s]\n", key_path, wstr_to_ascii(wide_name)) ;
+ }
+ else{
+ HKEY childKey = 0 ;
+ char* child_key_name = wstr_to_ascii( wide_name ) ;
+ char child_key_path[MAX_PATH] ;
+ sprintf(child_key_path,"%s\\%s", key_path, child_key_name) ;
+
+ if (!rapi_reg_open_key( key, child_key_name, &childKey ))
+ {
+ return 1 ;
+ }
+
+ //We have childkey now
+ //Do list_key on this
+ list_key( childKey , child_key_path, do_recurse) ;
+ }
}
- return 0;
+
+
+ return 0 ;
}
+
+
+
+int dump_registry()
+{
+ //First the HKLM
+ HKEY rootKey = HKEY_LOCAL_MACHINE ;
+
+ int result = 0 ;
+
+ result = list_key( rootKey, "HKEY_LOCAL_MACHINE", true) ;
+
+ if (result != 0){
+ return result ;
+ }
+
+ //Then the HKCU
+ rootKey = HKEY_CURRENT_USER ;
+
+ result = 0 ;
+
+ result = list_key( rootKey, "HKEY_CURRENT_USER", true ) ;
+
+ if (result != 0){
+ return result ;
+ }
+
+
+
+ //And finally the HKCR
+ rootKey = HKEY_CLASSES_ROOT ;
+
+ result = 0 ;
+
+ result = list_key( rootKey, "HKEY_CLASSES_ROOT", true ) ;
+
+ if (result != 0){
+ return result ;
+ }
+
+ return 0 ;
+}
+
+
+
+
+
int delete_val(HKEY key, LPCWSTR value_name)
{
#if 0
@@ -345,6 +483,7 @@
}
+
int read_val(char *parent_str, char *key_str, HKEY key, LPCWSTR value_name_wide)
{
int error;
@@ -453,7 +592,36 @@
if (!handle_parameters(argc,argv,&parent_str,&key_name,&value_name,&new_value))
goto exit;
-
+
+
+ //Add this before anything, since we don't need the
+ //parent_str etc..
+ if (action==ACTION_DUMP_REGISTRY){
+ if ((connection = rapi_connection_from_name(devname)) == NULL)
+ {
+ fprintf(stderr, "%s: Could not find configuration at path '%s'\n",
+ argv[0],
+ devname?devname:"(Default)");
+ goto exit;
+ }
+ rapi_connection_select(connection);
+ if (S_OK != (hr = CeRapiInit()))
+ {
+ fprintf(stderr, "%s: Unable to initialize RAPI: %s\n",
+ argv[0],
+ synce_strerror(hr));
+ goto exit;
+ }
+
+ result = dump_registry() ;
+ if (result != 0){
+ fprintf(stdout, "SOMETHING WENT WRONG!!!!\n" ) ;
+ }
+ goto exit;
+ }
+
+
+
/* handle abbreviations */
if (STR_EQUAL(parent_str, "HKCR"))
parent_str = "HKEY_CLASSES_ROOT";
@@ -516,7 +684,9 @@
if (action == ACTION_LISTKEY)
{
- result = list_key(key);
+ char path[255] ;
+ sprintf(path,"%s\\%s", parent_str, key_name ) ;
+ result = list_key(key, path, list_recurse);
goto exit;
}
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell. From the desktop to the data center, Linux is going
mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
SynCE-Devel mailing list
SynCE-Devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synce-devel