1 /* $Id: shell.c,v 1.1 2000/12/05 02:38:08 ekohl Exp $
3 * PROJECT : ReactOS Operating System
4 * DESCRIPTION: ReactOS' Native Shell
5 * LICENSE : See top level directory
18 HANDLE InputHandle
, OutputHandle
;
22 void debug_printf(char* fmt
, ...)
28 vsprintf(buffer
,fmt
,args
);
30 WriteConsoleA(OutputHandle
, buffer
, strlen(buffer
), NULL
, NULL
);
37 "Reactos Simple Shell\n(compiled on %s, at %s)\n",
43 void ExecuteCd(char* cmdline
)
45 if (!SetCurrentDirectoryA(cmdline
))
47 debug_printf("Invalid directory\n");
51 void ExecuteMd (char *cmdline
)
53 if (!CreateDirectoryA (cmdline
, NULL
))
55 debug_printf("Create Directory failed!\n");
59 void ExecuteDir(char* cmdline
)
62 WIN32_FIND_DATA FindData
;
67 shandle
= FindFirstFile("*",&FindData
);
69 if (shandle
==INVALID_HANDLE_VALUE
)
71 debug_printf("File not found\n\n");
76 debug_printf("%-15.15s",FindData
.cAlternateFileName
);
77 if(FindData
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
)
78 debug_printf("<DIR> "),nRep
++;
80 debug_printf(" %10d ",FindData
.nFileSizeLow
),nFile
++;
82 FileTimeToLocalFileTime(&FindData
.ftLastWriteTime
,&fTime
);
83 FileTimeToSystemTime(&fTime
, &sTime
);
84 debug_printf("%02d/%02d/%04d %02d:%02d:%02d "
85 ,sTime
.wMonth
,sTime
.wDay
,sTime
.wYear
86 ,sTime
.wHour
,sTime
.wMinute
,sTime
.wSecond
);
88 debug_printf("%s\n",FindData
.cFileName
);
89 } while(FindNextFile(shandle
,&FindData
));
90 debug_printf("\n %d files\n %d directories\n\n",nFile
,nRep
);
95 void ExecuteReboot(char* cmdline
)
97 NtShutdownSystem (ShutdownReboot
);
101 void ExecuteType(char* cmdline
)
107 FileHandle
= CreateFile(cmdline
,
114 if (FileHandle
== NULL
)
116 debug_printf("Unknown file\n");
119 while (ReadFile(FileHandle
,
125 debug_printf("%c",c
);
128 CloseHandle(FileHandle
);
131 int ExecuteProcess(char* name
, char* cmdline
, BOOL detached
)
133 PROCESS_INFORMATION ProcessInformation
;
134 STARTUPINFO StartupInfo
;
136 CHAR fullname
[MAX_PATH
];
139 /* append '.exe' if needed */
140 strcpy (fullname
, name
);
141 p
= strrchr (fullname
, '.');
143 (_stricmp (p
, ".exe") != 0))
145 strcat (fullname
, ".exe");
148 memset(&StartupInfo
, 0, sizeof(StartupInfo
));
149 StartupInfo
.cb
= sizeof (STARTUPINFO
);
150 StartupInfo
.lpTitle
= name
;
151 // set mode to default for new process
152 SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE
), ENABLE_LINE_INPUT
| ENABLE_PROCESSED_INPUT
| ENABLE_ECHO_INPUT
);
153 ret
= CreateProcessA(fullname
,
167 if (TRUE
== detached
)
171 debug_printf("%s detached:\n"
172 "\thProcess = %08X\n"
177 ProcessInformation
.hProcess
,
178 ProcessInformation
.hThread
,
179 ProcessInformation
.dwProcessId
,
180 ProcessInformation
.dwThreadId
);
181 CloseHandle(ProcessInformation
.hProcess
);
182 CloseHandle(ProcessInformation
.hThread
);
186 debug_printf("Could not detach %s\n", name
);
193 // debug_printf("ProcessInformation.hThread %x\n",
194 // ProcessInformation.hThread);
195 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
196 CloseHandle(ProcessInformation
.hProcess
);
197 // debug_printf("Thandle %x\n", ProcessInformation.hThread);
198 CloseHandle(ProcessInformation
.hThread
);
202 SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE
), 0 );
206 void ExecuteStart(char* CommandLine
)
208 char *ImageName
= CommandLine
;
212 && (*CommandLine
!= ' ')
213 && (*CommandLine
!= '\t')
217 *CommandLine
++ = '\0';
218 while ( (*CommandLine
)
219 && ( (*CommandLine
== ' ')
220 || (*CommandLine
== '\t')
232 ExecuteKill(char * lpPid
)
237 dwProcessId
= (DWORD
) atol(lpPid
);
238 debug_printf("dwProcessId %d\n",dwProcessId
);
239 hProcess
= OpenProcess(
244 if (NULL
== hProcess
)
247 "Could not open the process with PID = %d\n",
252 if (FALSE
== TerminateProcess(
258 "Could not terminate the process with PID = %d\n",
262 CloseHandle(hProcess
);
266 void ExecuteHelp (void * dummy
)
269 "A:\t\t\tCurrent drive is A:\n"
270 "C:\t\t\tCurrent drive is C:\n"
271 "cd [directory]\t\tChange current directory\n"
272 "dir [directory]\t\tList directory\n"
273 "exit\t\t\tTerminate the shell\n"
274 "help\t\t\tPrint this help message\n"
275 "kill [pid]\t\tKill process which PID is pid\n"
276 "md [directory]\t\tCreate a new directory\n"
277 "reboot\t\t\tRestart the system\n"
278 "start [program.exe]\tDetach program.exe\n"
279 "type [file]\t\tPrint the file on console\n"
280 "validate\t\tValidate the process' heap\n"
281 "ver\t\t\tPrint version information\n"
282 "[program.exe]\t\tStart synchronously program.exe\n\n"
286 void ExecuteCommand(char* line
)
291 if (isalpha(line
[0]) && line
[1] == ':' && line
[2] == 0)
293 char szPath
[MAX_PATH
];
296 /* save curent directory in environment variable */
297 GetCurrentDirectory (MAX_PATH
, szPath
);
299 strcpy (szVar
, "=A:");
300 szVar
[1] = toupper (szPath
[0]);
301 SetEnvironmentVariable (szVar
, szPath
);
303 /* check for current directory of new drive */
304 strcpy (szVar
, "=A:");
305 szVar
[1] = toupper (line
[0]);
306 if (GetEnvironmentVariable (szVar
, szPath
, MAX_PATH
) == 0)
308 /* no environment variable found */
309 strcpy (szPath
, "A:\\");
310 szPath
[0] = toupper (line
[0]);
313 /* set new current directory */
314 SetCurrentDirectory (szPath
);
315 GetCurrentDirectory (MAX_PATH
, szPath
);
316 if (szPath
[0] != (char)toupper (line
[0]))
317 debug_printf("Invalid drive\n");
323 while ((*tail
)!=' ' && (*tail
)!=0)
335 if (cmd
==NULL
|| *cmd
== '\0' )
339 if (strcmp(cmd
,"cd")==0)
344 if (strcmp(cmd
,"dir")==0)
349 if (strcmp(cmd
,"kill")==0)
354 if (strcmp(cmd
,"md")==0)
359 if (strcmp(cmd
,"reboot")==0)
364 if (strcmp(cmd
,"type")==0)
369 if (strcmp(cmd
,"ver")==0)
374 if (strcmp(cmd
,"validate")==0)
376 debug_printf("Validating heap...");
377 if (HeapValidate(GetProcessHeap(),0,NULL
))
379 debug_printf("succeeded\n");
383 debug_printf("failed\n");
387 if (strcmp(cmd
,"start") == 0)
392 if ((strcmp(cmd
,"help") * strcmp(cmd
,"?")) == 0)
397 if (strcmp(cmd
,"exit")==0)
399 if (bCanExit
== TRUE
)
405 if (ExecuteProcess(cmd
,tail
,FALSE
))
409 debug_printf("Unknown command '%s'\n", cmd
);
412 void ReadLine(char* line
)
415 UCHAR CurrentDir
[255];
419 GetCurrentDirectoryA(255,CurrentDir
);
420 debug_printf("%s>", CurrentDir
);
424 if ( !ReadConsoleA(InputHandle
, line
, 255 - length
, &Result
, NULL
) )
426 debug_printf("Failed to read from console\n");
429 for( c
= 0; c
< Result
; c
++ )
435 debug_printf("\b \b");
436 memmove( &line
[c
-1], &line
[c
], Result
- c
- 1 );
444 debug_printf( "\n" );
447 debug_printf( "%c", line
[c
] );
454 void ParseCommandLine (void)
456 char *pszCommandLine
;
458 pszCommandLine
= GetCommandLineA ();
459 _strupr (pszCommandLine
);
460 if (strstr (pszCommandLine
, "/P") != NULL
)
462 debug_printf("Permanent shell\n");
469 static char line
[255];
472 // clear line buffered mode
473 if( !SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE
), 0 ) )
475 debug_printf( "Error: could not set console mode, error: %d\n", GetLastError() );
476 return GetLastError();
478 InputHandle
= GetStdHandle(STD_INPUT_HANDLE
);
479 OutputHandle
= GetStdHandle(STD_OUTPUT_HANDLE
);
481 debug_printf("Shell Starting...\n");
488 ExecuteCommand(line
);