/** * @brief Checks wheter a command is registered for * being executed during the Windows boot process or not. * @param[in] command the name of the command's * executable, without the extension. * @return Positive value indicates that the command * is registered, zero indicates that it isn't, * negative value indicates a failure of the check. */ int winx_bootex_check(const wchar_t *command) { struct cmd *c, *list = NULL; int result = (-1); DbgCheck1(command,-1); if(!wcscmp(command,L"")) return 0; /* get list of registered commands */ if(get_boot_exec_list(&list) < 0) goto done; /* check for specified command presence */ result = 0; for(c = list; c; c = c->next){ if(cmd_compare(c->cmd,command) > 0){ result = 1; break; } if(c->next == list) break; } done: destroy_boot_exec_list(list); return result; }
/** * @brief Deregisters a command from being executed * during the Windows boot process. * @param[in] command the name of the command's * executable, without the extension. * @return Zero for success, negative value otherwise. */ int winx_bootex_unregister(const wchar_t *command) { struct cmd *c, *list = NULL; struct cmd *head, *next = NULL; int result = (-1); DbgCheck1(command,-1); if(!wcscmp(command,L"")) return 0; /* get list of registered commands */ if(get_boot_exec_list(&list) < 0) goto done; /* remove specified command */ for(c = list; c; c = next){ head = list; next = c->next; if(cmd_compare(c->cmd,command) > 0){ winx_list_remove((list_entry **)(void *)&list, (list_entry *)c); } if(list == NULL) break; if(next == head) break; } /* save list of registered commands */ result = save_boot_exec_list(list); done: destroy_boot_exec_list(list); return result; }
/** * @brief Queries an environment variable. * @param[in] name the environment variable name. * @return The value of the environment variable. * NULL indicates failure. * @note The returned string should be freed * by the winx_free call after its use. */ wchar_t *winx_getenv(wchar_t *name) { wchar_t *value; UNICODE_STRING n, v; NTSTATUS status; DbgCheck1(name,NULL); value = winx_malloc(MAX_ENV_VALUE_LENGTH * sizeof(wchar_t)); RtlInitUnicodeString(&n,name); v.Buffer = value; v.Length = 0; v.MaximumLength = MAX_ENV_VALUE_LENGTH * sizeof(wchar_t); status = RtlQueryEnvironmentVariable_U(NULL,&n,&v); if(!NT_SUCCESS(status)){ strace(status,"cannot query %ws",name); winx_free(value); return NULL; } if(value[0] == 0){ winx_free(value); return NULL; } return value; }
/** * @brief Releases a mutex. * @param[in] h the mutex handle. * @return Zero for success, * negative value otherwise. */ int winx_release_mutex(HANDLE h) { NTSTATUS status; DbgCheck1(h,-1); status = NtReleaseMutant(h,NULL); if(!NT_SUCCESS(status)){ strace(status,"cannot release mutex"); return (-1); } return 0; }
/** * @brief Creates a thread and starts them. * @param[in] start_addr the starting address of the thread. * @param[in] parameter pointer to the data passed to the thread routine. * @return Zero for success, negative value otherwise. * @note Look at the following example for the thread function prototype. * @par Example: * @code * DWORD WINAPI thread_proc(LPVOID parameter) * { * // do something * winx_exit_thread(0); * return 0; * } * winx_create_thread(thread_proc,NULL); * @endcode */ int winx_create_thread(PTHREAD_START_ROUTINE start_addr,PVOID parameter) { NTSTATUS status; HANDLE hThread; DbgCheck1(start_addr,-1); status = RtlCreateUserThread(NtCurrentProcess(),NULL, 0,0,0,0,start_addr,parameter,&hThread,NULL); if(!NT_SUCCESS(status)){ strace(status,"cannot create thread"); return (-1); } NtCloseSafe(hThread); return 0; }
/** * @brief Registers a command to be executed * during the Windows boot process. * @param[in] command the name of the command's * executable, without the extension. * @return Zero for success, negative value otherwise. * @note Command's executable must be placed inside * the system32 directory to be executed successfully. */ int winx_bootex_register(const wchar_t *command) { struct cmd *c, *list = NULL; struct cmd *prev_command = NULL; int cmd_found = 0; wchar_t *cmd_copy; int result = (-1); DbgCheck1(command,-1); if(!wcscmp(command,L"")) return 0; /* get list of registered commands */ if(get_boot_exec_list(&list) < 0) goto done; /* append specified command if necessary */ for(c = list; c; c = c->next){ if(cmd_compare(c->cmd,command) > 0){ cmd_found = 1; break; } if(c->next == list) break; } if(cmd_found){ result = 0; goto done; } cmd_copy = winx_wcsdup(command); if(cmd_copy == NULL){ mtrace(); goto done; } if(list) prev_command = list->prev; c = (struct cmd *)winx_list_insert( (list_entry **)(void *)&list, (list_entry *)prev_command, sizeof(struct cmd)); c->cmd = cmd_copy; /* save list of registered commands */ result = save_boot_exec_list(list); done: destroy_boot_exec_list(list); return result; }
/** * @brief Sets an environment variable. * @param[in] name the environment variable name. * @param[in] value the null-terminated value string. * NULL pointer causes a variable deletion. * @return Zero for success, negative value otherwise. * @note value buffer size must not exceed 32767 characters, * including terminal zero, as mentioned in MSDN. This is * because unsigned short data type can hold numbers * less than or equal to 32767. */ int winx_setenv(wchar_t *name, wchar_t *value) { UNICODE_STRING n, v; NTSTATUS status; DbgCheck1(name,-1); RtlInitUnicodeString(&n,name); if(value){ if(value[0]){ RtlInitUnicodeString(&v,value); status = RtlSetEnvironmentVariable(NULL,&n,&v); } else { status = RtlSetEnvironmentVariable(NULL,&n,NULL); } } else { status = RtlSetEnvironmentVariable(NULL,&n,NULL); } if(!NT_SUCCESS(status)){ strace(status,"cannot set %ws",name); return (-1); } return 0; }