1 /* $Id: regnav.c,v 1.2 1999/05/28 19:49:46 ea Exp $
5 * Copyright (c) 1998, 1999 Emanuele Aliberti
7 * --------------------------------------------------------------------
9 * This software is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
14 * This software is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this software; see the file COPYING.LIB. If
21 * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
22 * Cambridge, MA 02139, USA.
24 * --------------------------------------------------------------------
25 * ReactOS system registry console navigation tool.
35 #define INPUT_BUFFER_SIZE 512
36 #define COMMAND_NOT_FOUND NULL
37 #define CURRENT_PATH_SIZE 1024
39 LPCTSTR STR_HKEY_CLASSES_ROOT
= _TEXT("HKEY_CLASSES_ROOT");
40 LPCTSTR STR_HKEY_CURRENT_USER
= _TEXT("HKEY_CURRENT_USER");
41 LPCTSTR STR_HKEY_LOCAL_MACHINE
= _TEXT("HKEY_LOCAL_MACHINE");
42 LPCTSTR STR_HKEY_USERS
= _TEXT("HKEY_USERS");
43 LPCTSTR STR_HKEY_CURRENT_CONFIG
= _TEXT("HKEY_CURRENT_CONFIG");
44 LPCTSTR STR_HKEY_PERFORMANCE_DATA
= _TEXT("HKEY_PERFORMANCE_DATA");
47 LPTSTR app_name
= _TEXT("regnav");
48 LPCTSTR app_ver
= _TEXT("1.0.4");
49 HANDLE CurrentWorkingKey
= INVALID_HANDLE_VALUE
; /* \ */
50 TCHAR CurrentPath
[CURRENT_PATH_SIZE
] = _TEXT("\\");
55 /* === COMMANDS === */
57 #define CMDPROTOIF (int argc,LPTSTR argv[])
58 typedef int (*CommandFunction
) CMDPROTOIF
;
59 #define CMDPROTO(n) int n CMDPROTOIF
63 struct _COMMAND_DESCRIPTOR
66 LPCTSTR ShortDescription
;
68 CommandFunction Command
;
72 } COMMAND_DESCRIPTOR
, * PCOMMAND_DESCRIPTOR
;
88 _TEXT("Change the working key."),
89 _TEXT("CK key\n\nChange the working key."),
96 _TEXT("Terminate the application."),
97 _TEXT("EXIT\n\nTerminate the application."),
104 _TEXT("Print this commands summary, or a command's synopsis."),
105 _TEXT("HELP [command]\n\nPrint commands summary, or a command's synopsis."),
112 _TEXT("List a key's values and subkeys."),
113 _TEXT("LS [key]\n\nList a key's values and subkeys."),
120 _TEXT("Print the current working key."),
121 _TEXT("PWK\n\nPrint the current working key."),
128 _TEXT("Print version information."),
129 _TEXT("VER\n\nPrint version information."),
134 /* End of array marker */
139 /* === CMD MANAGER === */
143 DecodeVerb( LPCTSTR Name
)
148 CommandsTable
[i
].Name
;
152 if (0 == lstrcmpi(CommandsTable
[i
].Name
,Name
))
154 return & CommandsTable
[i
];
157 return COMMAND_NOT_FOUND
;
160 /* === Visual key name manager */
163 struct _SPLIT_KEY_NAME
167 TCHAR SubKey
[_MAX_PATH
];
169 } SPLIT_KEY_NAME
, * PSPLIT_KEY_NAME
;
180 TCHAR SystemKey
[64];
183 ZeroMemory( k
, sizeof (SPLIT_KEY_NAME
) );
184 k
->Hive
= INVALID_HANDLE_VALUE
;
186 if (r
[0] == _TEXT('\\') && r
[1] == _TEXT('\\'))
188 for ( r
+= 2, w
= k
->Host
;
189 (*r
&& (*r
!= _TEXT('\\')));
194 if (w
) *w
= _TEXT('\0');
197 if (*r
== _TEXT('\\')) ++r
;
199 (*r
&& (*r
!= _TEXT('\\')));
204 if (w
) *w
= _TEXT('\0');
205 if (0 == lstrcmpi(STR_HKEY_CLASSES_ROOT
, SystemKey
))
207 k
->Hive
= HKEY_CLASSES_ROOT
;
209 else if (0 == lstrcmpi(STR_HKEY_CURRENT_USER
, SystemKey
))
211 k
->Hive
= HKEY_CURRENT_USER
;
213 else if (0 == lstrcmpi(STR_HKEY_LOCAL_MACHINE
, SystemKey
))
215 k
->Hive
= HKEY_LOCAL_MACHINE
;
217 else if (0 == lstrcmpi(STR_HKEY_USERS
, SystemKey
))
219 k
->Hive
= HKEY_USERS
;
221 else if (0 == lstrcmpi(STR_HKEY_CURRENT_CONFIG
, SystemKey
))
223 k
->Hive
= HKEY_CURRENT_CONFIG
;
225 else if (0 == lstrcmpi(STR_HKEY_PERFORMANCE_DATA
, SystemKey
))
227 k
->Hive
= HKEY_PERFORMANCE_DATA
;
230 if (*r
== _TEXT('\\')) ++r
;
237 if (w
) *w
= _TEXT('\0');
242 /* === COMMANDS === */
245 /**********************************************************************
249 * Change the current working key.
256 if (0 == lstrcmp(argv
[1], _TEXT("..")))
258 _tprintf( _TEXT("Change to parent not implemented yet.\n") );
261 if (INVALID_HANDLE_VALUE
!= CurrentWorkingKey
)
263 RegCloseKey(CurrentWorkingKey
);
264 CurrentWorkingKey
= INVALID_HANDLE_VALUE
;
266 if (NULL
== ParseKeyName(argv
[1], &k
))
271 k
.Hive
, /* handle of open key */
272 k
.SubKey
, /* address of name of subkey to open */
274 (REGSAM
) KEY_ENUMERATE_SUB_KEYS
,/* security access mask */
275 & CurrentWorkingKey
/* address of handle of open key */
277 if (ERROR_SUCCESS
!= rv
)
279 PrintWin32Error(L
"RegOpenKeyEx",GetLastError());
286 /**********************************************************************
295 _tprintf( _TEXT("Quitting...\n") );
300 /**********************************************************************
308 PCOMMAND_DESCRIPTOR cd
= NULL
;
314 for ( CommandIndex
= 0;
315 (CommandsTable
[CommandIndex
].Name
);
321 CommandsTable
[CommandIndex
].Name
,
322 CommandsTable
[CommandIndex
].ShortDescription
327 if ((cd
= DecodeVerb(argv
[1])))
336 _TEXT("Unknown help item \"%s\".\n"),
343 /**********************************************************************
364 /* _self is always present */
365 _tprintf( _TEXT(".\\\n") );
366 /* _root directory? */
367 if (INVALID_HANDLE_VALUE
== CurrentWorkingKey
)
371 STR_HKEY_CLASSES_ROOT
375 STR_HKEY_CURRENT_USER
379 STR_HKEY_LOCAL_MACHINE
387 STR_HKEY_CURRENT_CONFIG
391 STR_HKEY_PERFORMANCE_DATA
395 /* _parent is present only if _self != _root
396 * (FIXME: change it when RegConnect... available)
398 _tprintf( _TEXT("..\\\n") );
399 /* Enumerate subkeys of the current key. */
401 cbName
= sizeof(Name
);
402 cbClass
= sizeof(Class
);
404 CurrentWorkingKey
, /* handle of key to enumerate */
405 dwIndexK
, /* index of subkey to enumerate */
406 Name
, /* address of buffer for subkey name */
407 & cbName
, /* address for size of subkey buffer */
409 Class
, /* address of buffer for class string */
410 & cbClass
, /* address for size of class buffer */
411 & ft
/* address for time key last written to */
413 if (ERROR_SUCCESS
== rv
)
415 FileTimeToSystemTime( & ft
, & st
);
418 _TEXT("%-32s\\ %4d-%02d-%02d %02d:%02d [%s]\n"),
420 st
.wYear
, st
.wMonth
, st
.wDay
,
421 st
.wHour
, st
.wMinute
,
426 _TEXT("%-32s\\ %4d-%02d-%02d %02d:%02d\n"),
428 st
.wYear
, st
.wMonth
, st
.wDay
,
433 } while (ERROR_SUCCESS
== rv
);
434 /* Enumerate key's values */
436 cbName
= sizeof(Name
);
437 cbData
= sizeof(Data
);
439 CurrentWorkingKey
, /* handle of key to query */
440 dwIndexV
, /* index of value to query */
441 Name
, /* address of buffer for value string */
442 & cbName
, /* address for size of value buffer */
444 & Type
, /* address of buffer for type code */
445 Data
, /* address of buffer for value data */
446 & cbData
/* address for size of data buffer */
448 if (ERROR_SUCCESS
== rv
)
454 _TEXT("%s = *REG_DWORD*\n"),
459 /* expand env vars */
466 _TEXT("%s = \"%s\"\n"),
474 } while (ERROR_SUCCESS
== rv
);
475 return (UINT
) dwIndexK
+ (UINT
) dwIndexV
;
479 /**********************************************************************
483 * Print the current working key.
487 if (INVALID_HANDLE_VALUE
== CurrentWorkingKey
)
489 _tprintf( _TEXT("[\\]\n") );
500 /**********************************************************************
504 * Print version information.
510 %s version %s (compiled on %s, at %s)\n\
511 ReactOS Console Registry Navigator\n\
512 Copyright (c) 1998, 1999 Emanuele Aliberti\n\n"),
522 /* === UTILITIES === */
534 register TCHAR
*c
= InputBuffer
;
541 && ( (*c
== _TEXT(' '))
542 || (*c
== _TEXT('\t'))
543 || (*c
== _TEXT('\n'))
553 && (*c
!= _TEXT(' '))
554 && (*c
!= _TEXT('\t'))
555 && (*c
!= _TEXT('\n'))
585 TCHAR InputBuffer
[INPUT_BUFFER_SIZE
];
586 PCOMMAND_DESCRIPTOR cd
;
588 LPTSTR LocalArgv
[ARGV_SIZE
];
596 (sizeof InputBuffer
/ sizeof (TCHAR
)),
599 if (0 == lstrlen(InputBuffer
)) continue;
600 LocalArgc
= ParseCommandLine(InputBuffer
, LocalArgv
);
601 if (LocalArgc
&& (cd
= DecodeVerb(LocalArgv
[0])))
603 if (LocalArgc
< cd
->MinArgc
)
606 _TEXT("Too few arguments. Type \"HELP %s\".\n"),
611 if (LocalArgc
> cd
->MaxArgc
)
614 _TEXT("Too many arguments. Type \"HELP %s\".\n"),
619 LastExitCode
= cd
->Command(
626 _TEXT("Unknown command (\"%s\").\n"),