3 * PROJECT : ReactOS Operating System
4 * DESCRIPTION: ReactOS' Native Shell
5 * LICENSE : See top level directory
18 HANDLE InputHandle, OutputHandle;
19 BOOL bCanExit = TRUE, bCanLinespace = TRUE;
22 void debug_printf(char* fmt, ...)
29 _vsnprintf(buffer,512,fmt,args);
31 WriteConsoleA(OutputHandle, buffer, strlen(buffer), &nbChar, NULL);
37 CONSOLE_SCREEN_BUFFER_INFO csbi;
40 GetConsoleScreenBufferInfo (OutputHandle, &csbi);
44 FillConsoleOutputAttribute (OutputHandle, csbi.wAttributes, (csbi.dwSize.X)*(csbi.dwSize.Y), coPos, &dwWritten);
45 FillConsoleOutputCharacter (OutputHandle, _T(' '), (csbi.dwSize.X)*(csbi.dwSize.Y), coPos, &dwWritten);
46 SetConsoleCursorPosition (OutputHandle, coPos);
52 "Reactos Simple Shell\n(compiled on %s, at %s)\n",
58 void ExecuteCd(char* cmdline)
60 if (!SetCurrentDirectoryA(cmdline))
62 debug_printf("Invalid directory\n");
66 void ExecuteMd (char *cmdline)
68 if (!CreateDirectoryA (cmdline, NULL))
70 debug_printf("Create Directory failed!\n");
74 void ExecuteDir(char* cmdline)
77 WIN32_FIND_DATA FindData;
82 shandle = FindFirstFile("*",&FindData);
84 if (shandle==INVALID_HANDLE_VALUE)
86 debug_printf("File not found\n");
91 debug_printf("%-15.15s",FindData.cAlternateFileName);
92 if(FindData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
93 debug_printf("<DIR> "),nRep++;
95 debug_printf(" %10d ",FindData.nFileSizeLow),nFile++;
97 FileTimeToLocalFileTime(&FindData.ftLastWriteTime ,&fTime);
98 FileTimeToSystemTime(&fTime, &sTime);
99 debug_printf("%02d/%02d/%04d %02d:%02d:%02d "
100 ,sTime.wMonth,sTime.wDay,sTime.wYear
101 ,sTime.wHour,sTime.wMinute,sTime.wSecond);
103 debug_printf("%s\n",FindData.cFileName);
104 } while(FindNextFile(shandle,&FindData));
105 debug_printf("\n %d files\n %d directories\n",nFile,nRep);
110 void ExecuteReboot(char* cmdline)
112 NtShutdownSystem (ShutdownReboot);
116 void ExecuteShutdown(char* cmdline)
118 NtShutdownSystem (ShutdownNoReboot);
122 void ExecuteType(char* cmdline)
129 FileHandle = CreateFile(cmdline,
136 if (FileHandle == NULL)
138 debug_printf("Unknown file\n");
143 Success = ReadFile(FileHandle,
150 debug_printf("%c",c);
153 } while (Success && Result > 0);
154 CloseHandle(FileHandle);
157 int ExecuteProcess(char* name, char* cmdline, BOOL detached)
159 PROCESS_INFORMATION ProcessInformation;
160 STARTUPINFO StartupInfo;
165 /* append '.exe' if needed */
166 strcpy (fullname, name);
167 p = strrchr (fullname, '.');
169 (_stricmp (p, ".exe") != 0))
171 strcat (fullname, ".exe");
174 memset(&StartupInfo, 0, sizeof(StartupInfo));
175 StartupInfo.cb = sizeof (STARTUPINFO);
176 StartupInfo.lpTitle = name;
177 if( cmdline && *cmdline )
178 *(cmdline-1) = ' '; // fix command line so it is the FULL command, including exe name
179 ret = CreateProcessA(fullname,
193 if (TRUE == detached)
197 debug_printf("\"%s\" detached:\n"
198 "\thProcess = %08X\n"
203 ProcessInformation.hProcess,
204 ProcessInformation.hThread,
205 ProcessInformation.dwProcessId,
206 ProcessInformation.dwThreadId);
207 CloseHandle(ProcessInformation.hProcess);
208 CloseHandle(ProcessInformation.hThread);
212 debug_printf("Could not detach %s\n", name);
219 // debug_printf("ProcessInformation.hThread %x\n",
220 // ProcessInformation.hThread);
221 WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
222 CloseHandle(ProcessInformation.hProcess);
223 // debug_printf("Thandle %x\n", ProcessInformation.hThread);
224 CloseHandle(ProcessInformation.hThread);
230 void ExecuteStart(char* CommandLine)
232 char *ImageName = CommandLine;
236 && (*CommandLine != ' ')
237 && (*CommandLine != '\t')
241 *CommandLine++ = '\0';
242 while ( (*CommandLine)
243 && ( (*CommandLine == ' ')
244 || (*CommandLine == '\t')
256 ExecuteKill(char * lpPid)
261 dwProcessId = (DWORD) atol(lpPid);
262 debug_printf("Killing PID %d...\n",dwProcessId);
263 hProcess = OpenProcess(
268 if (NULL == hProcess)
271 "Could not open the process with PID = %d\n",
276 if (FALSE == TerminateProcess(
282 "Could not terminate the process with PID = %d\n",
286 CloseHandle(hProcess);
290 void ExecuteHelp (void * dummy)
293 "A:\t\t\tCurrent drive is A:\n"
\r
294 "C:\t\t\tCurrent drive is C:\n"
295 "cd [directory]\t\tChange current directory\n"
296 "dir [directory]\t\tList directory\n"
297 "exit\t\t\tTerminate the shell\n"
298 "help\t\t\tPrint this help message\n"
299 "kill [pid]\t\tKill process which PID is pid\n"
300 "md [directory]\t\tCreate a new directory\n"
301 "reboot\t\t\tRestart the system\n"
302 "start [program.exe]\tDetach program.exe\n"
303 "type [file]\t\tPrint the file on console\n"
304 "validate\t\tValidate the process' heap\n"
305 "ver\t\t\tPrint version information\n"
306 "[program.exe]\t\tStart synchronously program.exe\n"
310 void ExecuteCommand(char* line)
315 if (isalpha(line[0]) && line[1] == ':' && line[2] == 0)
317 char szPath[MAX_PATH];
320 /* save curent directory in environment variable */
321 GetCurrentDirectory (MAX_PATH, szPath);
323 strcpy (szVar, "=A:");
324 szVar[1] = toupper (szPath[0]);
325 SetEnvironmentVariable (szVar, szPath);
327 /* check for current directory of new drive */
328 strcpy (szVar, "=A:");
329 szVar[1] = toupper (line[0]);
330 if (GetEnvironmentVariable (szVar, szPath, MAX_PATH) == 0)
332 /* no environment variable found */
333 strcpy (szPath, "A:\\");
334 szPath[0] = toupper (line[0]);
337 /* set new current directory */
338 SetCurrentDirectory (szPath);
339 GetCurrentDirectory (MAX_PATH, szPath);
340 if (szPath[0] != (char)toupper (line[0]))
341 debug_printf("Invalid drive\n");
347 while ((*tail)!=' ' && (*tail)!=0)
359 if (cmd==NULL || *cmd == '\0' )
363 if (strcmp(cmd,"cd")==0)
368 if (strcmp(cmd,"dir")==0)
373 if (strcmp(cmd,"kill")==0)
378 if (strcmp(cmd,"md")==0)
383 if (strcmp(cmd,"reboot")==0)
388 if (strcmp(cmd,"shutdown")==0)
390 ExecuteShutdown(tail);
393 if (strcmp(cmd,"type")==0)
398 if (strcmp(cmd,"ver")==0)
403 if (strcmp(cmd,"validate")==0)
405 debug_printf("Validating heap...");
406 if (HeapValidate(GetProcessHeap(),0,NULL))
408 debug_printf("succeeded\n");
412 debug_printf("failed\n");
416 if (strcmp(cmd,"start") == 0)
421 if ((strcmp(cmd,"help") * strcmp(cmd,"?")) == 0)
426 if (strcmp(cmd,"exit")==0)
428 if (bCanExit == TRUE)
434 if (strcmp(cmd,"cls") == 0)
437 bCanLinespace = FALSE;
440 if (ExecuteProcess(cmd,tail,FALSE))
444 debug_printf("Unknown command '%s'\n", cmd);
447 void ReadLine(char* line)
450 UCHAR CurrentDir[255];
452 GetCurrentDirectoryA(255,CurrentDir);
453 debug_printf("%s>", CurrentDir);
454 if ( !ReadConsoleA(InputHandle, line, 252, &Result, NULL) )
456 debug_printf("Failed to read from console\n");
459 // If the \n is in there, so is the \r so null it, otherwise, null the last char
460 if( line[Result-1] == '\n' )
467 void ParseCommandLine (void)
469 char *pszCommandLine;
471 pszCommandLine = GetCommandLineA ();
472 _strupr (pszCommandLine);
473 if (strstr (pszCommandLine, "/P") != NULL)
475 debug_printf("Permanent shell\n");
482 static char line[256];
485 InputHandle = GetStdHandle(STD_INPUT_HANDLE);
486 OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
493 ExecuteCommand(line);
498 bCanLinespace = TRUE;