1 /* $Id: regnav.c,v 1.3 2000/05/28 17:44:53 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.
36 #define INPUT_BUFFER_SIZE 512
37 #define COMMAND_NOT_FOUND NULL
38 #define CURRENT_PATH_SIZE 1024
40 LPCTSTR STR_HKEY_CLASSES_ROOT
= _TEXT("HKEY_CLASSES_ROOT");
41 LPCTSTR STR_HKEY_CURRENT_USER
= _TEXT("HKEY_CURRENT_USER");
42 LPCTSTR STR_HKEY_LOCAL_MACHINE
= _TEXT("HKEY_LOCAL_MACHINE");
43 LPCTSTR STR_HKEY_USERS
= _TEXT("HKEY_USERS");
44 LPCTSTR STR_HKEY_CURRENT_CONFIG
= _TEXT("HKEY_CURRENT_CONFIG");
45 LPCTSTR STR_HKEY_PERFORMANCE_DATA
= _TEXT("HKEY_PERFORMANCE_DATA");
48 LPTSTR app_name
= _TEXT("regnav");
49 LPCTSTR app_ver
= _TEXT("1.0.4");
50 HANDLE CurrentWorkingKey
= INVALID_HANDLE_VALUE
; /* \ */
51 TCHAR CurrentPath
[CURRENT_PATH_SIZE
] = _TEXT("\\");
56 /* === COMMANDS === */
58 #define CMDPROTOIF (int argc,LPTSTR argv[])
59 typedef int (*CommandFunction
) CMDPROTOIF
;
60 #define CMDPROTO(n) int n CMDPROTOIF
64 struct _COMMAND_DESCRIPTOR
67 LPCTSTR ShortDescription
;
69 CommandFunction Command
;
73 } COMMAND_DESCRIPTOR
, * PCOMMAND_DESCRIPTOR
;
89 _TEXT("Change the working key."),
90 _TEXT("CK key\n\nChange the working key."),
97 _TEXT("Terminate the application."),
98 _TEXT("EXIT\n\nTerminate the application."),
105 _TEXT("Print this commands summary, or a command's synopsis."),
106 _TEXT("HELP [command]\n\nPrint commands summary, or a command's synopsis."),
113 _TEXT("List a key's values and subkeys."),
114 _TEXT("LS [key]\n\nList a key's values and subkeys."),
121 _TEXT("Print the current working key."),
122 _TEXT("PWK\n\nPrint the current working key."),
129 _TEXT("Print version information."),
130 _TEXT("VER\n\nPrint version information."),
135 /* End of array marker */
140 /* === CMD MANAGER === */
144 DecodeVerb( LPCTSTR Name
)
149 CommandsTable
[i
].Name
;
153 if (0 == lstrcmpi(CommandsTable
[i
].Name
,Name
))
155 return & CommandsTable
[i
];
158 return COMMAND_NOT_FOUND
;
161 /* === Visual key name manager */
164 struct _SPLIT_KEY_NAME
168 TCHAR SubKey
[_MAX_PATH
];
170 } SPLIT_KEY_NAME
, * PSPLIT_KEY_NAME
;
181 TCHAR SystemKey
[64];
184 ZeroMemory( k
, sizeof (SPLIT_KEY_NAME
) );
185 k
->Hive
= INVALID_HANDLE_VALUE
;
187 if (r
[0] == _TEXT('\\') && r
[1] == _TEXT('\\'))
189 for ( r
+= 2, w
= k
->Host
;
190 (*r
&& (*r
!= _TEXT('\\')));
195 if (w
) *w
= _TEXT('\0');
198 if (*r
== _TEXT('\\')) ++r
;
200 (*r
&& (*r
!= _TEXT('\\')));
205 if (w
) *w
= _TEXT('\0');
206 if (0 == lstrcmpi(STR_HKEY_CLASSES_ROOT
, SystemKey
))
208 k
->Hive
= HKEY_CLASSES_ROOT
;
210 else if (0 == lstrcmpi(STR_HKEY_CURRENT_USER
, SystemKey
))
212 k
->Hive
= HKEY_CURRENT_USER
;
214 else if (0 == lstrcmpi(STR_HKEY_LOCAL_MACHINE
, SystemKey
))
216 k
->Hive
= HKEY_LOCAL_MACHINE
;
218 else if (0 == lstrcmpi(STR_HKEY_USERS
, SystemKey
))
220 k
->Hive
= HKEY_USERS
;
222 else if (0 == lstrcmpi(STR_HKEY_CURRENT_CONFIG
, SystemKey
))
224 k
->Hive
= HKEY_CURRENT_CONFIG
;
226 else if (0 == lstrcmpi(STR_HKEY_PERFORMANCE_DATA
, SystemKey
))
228 k
->Hive
= HKEY_PERFORMANCE_DATA
;
231 if (*r
== _TEXT('\\')) ++r
;
238 if (w
) *w
= _TEXT('\0');
243 /* === COMMANDS === */
246 /**********************************************************************
250 * Change the current working key.
257 if (0 == lstrcmp(argv
[1], _TEXT("..")))
259 _tprintf( _TEXT("Change to parent not implemented yet.\n") );
262 if (INVALID_HANDLE_VALUE
!= CurrentWorkingKey
)
264 RegCloseKey(CurrentWorkingKey
);
265 CurrentWorkingKey
= INVALID_HANDLE_VALUE
;
267 if (NULL
== ParseKeyName(argv
[1], &k
))
272 k
.Hive
, /* handle of open key */
273 k
.SubKey
, /* address of name of subkey to open */
275 (REGSAM
) KEY_ENUMERATE_SUB_KEYS
,/* security access mask */
276 & CurrentWorkingKey
/* address of handle of open key */
278 if (ERROR_SUCCESS
!= rv
)
280 PrintWin32Error(L
"RegOpenKeyEx",GetLastError());
287 /**********************************************************************
296 _tprintf( _TEXT("Quitting...\n") );
301 /**********************************************************************
309 PCOMMAND_DESCRIPTOR cd
= NULL
;
315 for ( CommandIndex
= 0;
316 (CommandsTable
[CommandIndex
].Name
);
322 CommandsTable
[CommandIndex
].Name
,
323 CommandsTable
[CommandIndex
].ShortDescription
328 if ((cd
= DecodeVerb(argv
[1])))
337 _TEXT("Unknown help item \"%s\".\n"),
344 /**********************************************************************
365 /* _self is always present */
366 _tprintf( _TEXT(".\\\n") );
367 /* _root directory? */
368 if (INVALID_HANDLE_VALUE
== CurrentWorkingKey
)
372 STR_HKEY_CLASSES_ROOT
376 STR_HKEY_CURRENT_USER
380 STR_HKEY_LOCAL_MACHINE
388 STR_HKEY_CURRENT_CONFIG
392 STR_HKEY_PERFORMANCE_DATA
396 /* _parent is present only if _self != _root
397 * (FIXME: change it when RegConnect... available)
399 _tprintf( _TEXT("..\\\n") );
400 /* Enumerate subkeys of the current key. */
402 cbName
= sizeof(Name
);
403 cbClass
= sizeof(Class
);
405 CurrentWorkingKey
, /* handle of key to enumerate */
406 dwIndexK
, /* index of subkey to enumerate */
407 Name
, /* address of buffer for subkey name */
408 & cbName
, /* address for size of subkey buffer */
410 Class
, /* address of buffer for class string */
411 & cbClass
, /* address for size of class buffer */
412 & ft
/* address for time key last written to */
414 if (ERROR_SUCCESS
== rv
)
416 FileTimeToSystemTime( & ft
, & st
);
419 _TEXT("%-32s\\ %4d-%02d-%02d %02d:%02d [%s]\n"),
421 st
.wYear
, st
.wMonth
, st
.wDay
,
422 st
.wHour
, st
.wMinute
,
427 _TEXT("%-32s\\ %4d-%02d-%02d %02d:%02d\n"),
429 st
.wYear
, st
.wMonth
, st
.wDay
,
434 } while (ERROR_SUCCESS
== rv
);
435 /* Enumerate key's values */
437 cbName
= sizeof(Name
);
438 cbData
= sizeof(Data
);
440 CurrentWorkingKey
, /* handle of key to query */
441 dwIndexV
, /* index of value to query */
442 Name
, /* address of buffer for value string */
443 & cbName
, /* address for size of value buffer */
445 & Type
, /* address of buffer for type code */
446 Data
, /* address of buffer for value data */
447 & cbData
/* address for size of data buffer */
449 if (ERROR_SUCCESS
== rv
)
455 _TEXT("%s = *REG_DWORD*\n"),
460 /* expand env vars */
467 _TEXT("%s = \"%s\"\n"),
475 } while (ERROR_SUCCESS
== rv
);
476 return (UINT
) dwIndexK
+ (UINT
) dwIndexV
;
480 /**********************************************************************
484 * Print the current working key.
488 if (INVALID_HANDLE_VALUE
== CurrentWorkingKey
)
490 _tprintf( _TEXT("[\\]\n") );
501 /**********************************************************************
505 * Print version information.
511 %s version %s (compiled on %s, at %s)\n\
512 ReactOS Console Registry Navigator\n\
513 Copyright (c) 1998, 1999 Emanuele Aliberti\n\n"),
523 /* === UTILITIES === */
535 register TCHAR
*c
= InputBuffer
;
542 && ( (*c
== _TEXT(' '))
543 || (*c
== _TEXT('\t'))
544 || (*c
== _TEXT('\n'))
554 && (*c
!= _TEXT(' '))
555 && (*c
!= _TEXT('\t'))
556 && (*c
!= _TEXT('\n'))
586 TCHAR InputBuffer
[INPUT_BUFFER_SIZE
];
587 PCOMMAND_DESCRIPTOR cd
;
589 LPTSTR LocalArgv
[ARGV_SIZE
];
597 (sizeof InputBuffer
/ sizeof (TCHAR
)),
600 if (0 == lstrlen(InputBuffer
)) continue;
601 LocalArgc
= ParseCommandLine(InputBuffer
, LocalArgv
);
602 if (LocalArgc
&& (cd
= DecodeVerb(LocalArgv
[0])))
604 if (LocalArgc
< cd
->MinArgc
)
607 _TEXT("Too few arguments. Type \"HELP %s\".\n"),
612 if (LocalArgc
> cd
->MaxArgc
)
615 _TEXT("Too many arguments. Type \"HELP %s\".\n"),
620 LastExitCode
= cd
->Command(
627 _TEXT("Unknown command (\"%s\").\n"),