15void report_error_code(DWORD err);
17void get_cwd(
unsigned int buffer_size, os_char *buffer) {
18 DWORD status = GetCurrentDirectory((DWORD)buffer_size, (LPSTR)buffer);
19 if(status == 0 || status > buffer_size) {
20 report_error_code(GetLastError());
25 if(!SetCurrentDirectory(new_dir)) {
26 report_error_code(GetLastError());
32void report_error_code(DWORD error) {
34 case ERROR_FILE_NOT_FOUND:
37 case ERROR_INVALID_NAME:
38 format_error(
"Filename, directory name, or volume label syntax is incorrect\n");
43 case ERROR_PATH_NOT_FOUND:
46 case ERROR_ENVVAR_NOT_FOUND:
49 case ERROR_ACCESS_DENIED:
60 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
61 CONSOLE_SCREEN_BUFFER_INFO csbi;
62 SMALL_RECT scrollRect;
67 if(!GetConsoleScreenBufferInfo(hConsole, &csbi)) {
74 scrollRect.Right = csbi.dwSize.X;
75 scrollRect.Bottom = csbi.dwSize.Y;
79 scrollTarget.Y = (SHORT)(0 - csbi.dwSize.Y);
82 fill.Char.UnicodeChar = TEXT(
' ');
83 fill.Attributes = csbi.wAttributes;
86 ScrollConsoleScreenBuffer(hConsole, &scrollRect, NULL, scrollTarget, &fill);
89 csbi.dwCursorPosition.X = 0;
90 csbi.dwCursorPosition.Y = 0;
92 SetConsoleCursorPosition(hConsole, csbi.dwCursorPosition);
96bool is_empty_str(os_char *str) {
97 return !strcmp(str,
"");
100void extract_from_args(
const struct args args, os_char **p_command_line) {
105 for(
int i = 1; i <
args.
argc; ++i) {
113 os_char *command_line = malloc((len + 1) *
sizeof(os_char));
116 sprintf(command_line,
"\"%s\"",
args.
argv[0]);
119 for(
int i = 1; i <
args.
argc; ++i) {
123 sprintf(command_line + len,
" \"%s\"",
args.
argv[i]);
128 command_line[len] =
'\0';
130 *p_command_line = command_line;
134 HANDLE hProcess = OpenProcess(PROCESS_TERMINATE,
false, proc_id);
136 if(hProcess == NULL) {
137 CloseHandle(hProcess);
140 }
else if(TerminateProcess(hProcess, 0)) {
141 CloseHandle(hProcess);
145 CloseHandle(hProcess);
146 format_error(
"Can't terminate process with id %d\n.", proc_id);
154 HANDLE threadsSnapshot = INVALID_HANDLE_VALUE;
155 threadsSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
157 if(threadsSnapshot == INVALID_HANDLE_VALUE) {
162 THREADENTRY32 threadEntry;
163 threadEntry.dwSize =
sizeof(THREADENTRY32);
164 Thread32First(threadsSnapshot, &threadEntry);
166 if(threadEntry.th32OwnerProcessID == proc_id) {
167 HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE,
168 threadEntry.th32ThreadID);
169 ResumeThread(hThread);
170 CloseHandle(hThread);
173 }
while(Thread32Next(threadsSnapshot, &threadEntry));
179 format_error(
"Can't find process with ID %d\n", proc_id);
184 HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
185 if(hProcess == INVALID_HANDLE_VALUE) {
191 pe.dwSize =
sizeof(PROCESSENTRY32);
192 Process32First(hProcess, &pe);
194 int countChildProcess = 0;
196 if(pe.th32ParentProcessID == proc_id) {
198 pe.cntThreads, pe.szExeFile);
201 }
while(Process32Next(hProcess, &pe));
203 CloseHandle(hProcess);
204 if(!countChildProcess) {
211 if(DeleteFile(filename)) {
215 report_error_code(GetLastError());
219bool lsdir(
const os_char *dir) {
220 WIN32_FIND_DATA data;
221 LARGE_INTEGER fileSize;
224 unsigned int dir_len = strlen(dir);
225 os_char *combined = (os_char *)malloc((dir_len + 3) *
sizeof(os_char));
227 memcpy(combined, dir, dir_len);
228 memcpy(combined + dir_len,
"/*", 2);
229 combined[dir_len + 2] =
'\0';
231 HANDLE hFind = FindFirstFile(combined, &data);
233 if(hFind != INVALID_HANDLE_VALUE) {
235 if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
241 }
while(FindNextFile(hFind, &data) != 0);
246 if(countFile)
return true;
253 signal(SIGINT, SIG_IGN);
256 os_char *command_line = NULL;
258 extract_from_args(
args, &command_line);
261 PROCESS_INFORMATION pi;
263 ZeroMemory(&si,
sizeof(si));
265 ZeroMemory(&pi,
sizeof(pi));
267 const unsigned int len = strlen(command_line);
268 os_char *tmp_command_line = malloc((len + 1) *
sizeof(os_char));
269 memcpy(tmp_command_line, command_line, len *
sizeof(os_char));
270 tmp_command_line[len] =
'\0';
286 free(tmp_command_line);
287 report_error_code(GetLastError());
291 free(tmp_command_line);
295 WaitForSingleObject(pi.hProcess, INFINITE);
297# define exit_cleanup(res) \
299 CloseHandle(pi.hProcess); \
300 CloseHandle(pi.hThread); \
303 if(GetExitCodeProcess(pi.hProcess, &exit_code) == 0) {
304 report_error_code(GetLastError());
317 CloseHandle(pi.hProcess);
318 CloseHandle(pi.hThread);
325 if(SetEnvironmentVariable(name, val == NULL ?
"" : val)) {
328 report_error_code(GetLastError());
333 if(SetEnvironmentVariableA(name, NULL)) {
336 report_error_code(GetLastError());
340bool get_shell_env(
const os_char *var,
unsigned int buffer_size, os_char *buffer) {
341 DWORD res = GetEnvironmentVariable(var, buffer, buffer_size);
342 DWORD last_err = GetLastError();
343 if(res == 0 && last_err != ERROR_SUCCESS) {
344 report_error_code(last_err);
346 }
else if(res >= buffer_size) {
355 DWORD res = GetEnvironmentVariable(var, buffer,
PATH_MAX);
356 DWORD last_err = GetLastError();
357 if((res == 0 && last_err != ERROR_SUCCESS) || res >=
PATH_MAX) {
365 unsigned int res_len = 0;
367 os_char *ptr = GetEnvironmentStrings();
368 for(os_char *i = ptr; *i !=
'\0';) {
369 const unsigned int len = strlen(i);
370 const unsigned int res_new_length = res_len + len + 1;
372 while(res_new_length >= reserve_len) {
374 os_char *tmp = realloc(res, reserve_len);
378 FreeEnvironmentStrings(ptr);
383 memcpy(res + res_len, i, len);
384 res_len = res_new_length;
385 *(res + res_len - 1) =
'\n';
388 FreeEnvironmentStrings(ptr);
390 *(res + res_len) =
'\0';
397 SECURITY_ATTRIBUTES sa;
398 sa.nLength =
sizeof(sa);
399 sa.lpSecurityDescriptor = NULL;
400 sa.bInheritHandle = TRUE;
402 HANDLE hFIle = CreateFile(
408 FILE_ATTRIBUTE_NORMAL,
411 if(hFIle == INVALID_HANDLE_VALUE) {
416 PROCESS_INFORMATION pi;
420 ZeroMemory(&pi,
sizeof(PROCESS_INFORMATION));
421 ZeroMemory(&si,
sizeof(STARTUPINFO));
423 si.cb =
sizeof(STARTUPINFO);
424 si.dwFlags |= STARTF_USESTDHANDLES;
425 si.hStdInput = hFIle;
426 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
427 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
442 format_error(
"Cannot create process %s, exit code: %d!\n", file, GetLastError());
448 WaitForSingleObject(pi.hProcess, INFINITE);
451 CloseHandle(pi.hProcess);
452 CloseHandle(pi.hThread);
461 HANDLE hSnapshot = INVALID_HANDLE_VALUE;
462 hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
463 if(hSnapshot == INVALID_HANDLE_VALUE)
467 pe.dwSize =
sizeof(PROCESSENTRY32);
468 Process32First(hSnapshot, &pe);
470 printf(
"PID: %6lu PPID: %6lu T: %3lu Name: %s \n", pe.th32ProcessID, pe.th32ParentProcessID, pe.cntThreads, pe.szExeFile);
471 }
while(Process32Next(hSnapshot, &pe));
473 CloseHandle(hSnapshot);
482 format_output(
"The current time is: %02d:%02d:%02d.\n", st.wHour, st.wMinute, st.wSecond);
490 format_output(
"The current date is: %02d/%02d/%04d.\n", st.wDay, st.wMonth, st.wYear);
497 HANDLE threadsSnapshot = INVALID_HANDLE_VALUE;
498 threadsSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
499 if(threadsSnapshot == INVALID_HANDLE_VALUE) {
503 THREADENTRY32 threadEntry;
504 threadEntry.dwSize =
sizeof(THREADENTRY32);
505 Thread32First(threadsSnapshot, &threadEntry);
508 if(threadEntry.th32OwnerProcessID == proc_id) {
509 HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, threadEntry.th32ThreadID);
510 SuspendThread(hThread);
511 CloseHandle(hThread);
514 }
while(Thread32Next(threadsSnapshot, &threadEntry));
520 format_error(
"Can't find process with ID %d\n", proc_id);
#define ENVS_RESERVE_SIZE
void format_output(char *fmt,...)
Used format_xxx instead of printf and such for uniform output.
void format_success(char *fmt,...)
Used format_xxx instead of printf and such for uniform output.
void format_error(char *fmt,...)
Used format_xxx instead of printf and such for uniform output.
bool stop_proccess(int proc_id)
Stop a process use it ID.
bool get_date()
Get current date.
bool has_shell_env(const os_char *var)
Check if a variable environment exists.
bool change_cwd(const os_char *new_dir)
Attempt to change current working directory.
bool get_shell_env(const os_char *var, unsigned int buffer_size, os_char *buffer)
Get value of an an environment variable.
void clear_screen()
Clear the console.
bool kill_process(int proc_id)
Kill a process.
bool show_child_processes(int proc_id)
Show child processes.
bool enum_proc()
List all running processes.
bool lsdir(const os_char *dir)
List of files or folders in specific directory.
bool minibat(const struct args args)
Launch shell executable and execute the file specified by args.argv[0]
os_char * get_all_shell_env_display()
Get all current environment variable.
bool delete_file(const os_char *filename)
Delete a specific file.
bool set_shell_env(const os_char *name, const os_char *val)
Set environment variable of the shell process.
bool launch_executable(const struct args args)
Launch the executable.
bool get_time()
Get current time.
bool unset_shell_env(const os_char *name)
Unset environment variable of the shell process.
void get_cwd(unsigned int buffer_size, os_char *buffer)
Fetch current working directory and copy them into buffer
bool resume(int proc_id)
Resume running a process.
Result after parsing an arbitrary string.