forked from KolibriOS/kolibrios
Compare commits
7 Commits
update-ksy
...
add-thread
| Author | SHA1 | Date | |
|---|---|---|---|
| 12732925d4 | |||
| fe9eb967c8 | |||
| 9ce9864325 | |||
| c40ecec087 | |||
| dc0da05c55 | |||
| 68c16f077e | |||
| 1cfcfaf627 |
@@ -159,7 +159,7 @@ typedef struct {
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t cpu_usage; // CPU usage (cycles per secondes)
|
||||
uint32_t cpu_usage; // CPU usage (cycles per secondgoes)
|
||||
uint16_t pos_in_window_stack; // position of the thread window in the window stack
|
||||
uint16_t slot_num_window_stack; // slot number in window stack
|
||||
uint16_t __reserved1; // reserved
|
||||
@@ -240,30 +240,6 @@ typedef union {
|
||||
};
|
||||
} ksys_signal_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t a, b, c, d;
|
||||
uint8_t debug_label;
|
||||
uint8_t ABI_low;
|
||||
uint8_t ABI_high;
|
||||
uint32_t commit_id;
|
||||
uint16_t reserved;
|
||||
uint16_t commit_count;
|
||||
} ksys_kernel_version_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total_ram_pages;
|
||||
uint32_t free_ram_pages;
|
||||
uint32_t page_faults;
|
||||
uint32_t kernel_heap_size;
|
||||
uint32_t kernel_heap_free;
|
||||
uint32_t kernel_heap_total_blocks;
|
||||
uint32_t kernel_heap_free_blocks;
|
||||
uint32_t kernel_heap_largest_free_block;
|
||||
uint32_t kernel_heap_largest_alloc_block;
|
||||
|
||||
} ksys_memory_info_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef rgb_t ksys_bitmap_t;
|
||||
@@ -809,40 +785,6 @@ KOSAPI void _ksys_shutdown(uint32_t shd_param)
|
||||
asm_inline("int $0x40" ::"a"(18), "b"(9), "c"(shd_param));
|
||||
}
|
||||
|
||||
/*====== Function 18, subfunction 10 - minimize current window. ========*/
|
||||
|
||||
KOSAPI void _ksys_minimize_current_windows()
|
||||
{
|
||||
asm_inline(
|
||||
"int $0x40" ::"a"(18), "b"(10));
|
||||
}
|
||||
|
||||
/*========== Function 18, subfunction 13 - get kernel version. =========*/
|
||||
|
||||
KOSAPI int _ksys_get_kernel_version(ksys_kernel_version_t* info)
|
||||
{
|
||||
int err;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(18), "b"(13), "c"(info)
|
||||
: "memory");
|
||||
return err;
|
||||
}
|
||||
|
||||
/*========= Function 18, subfunction 15 - move mouse to center. ========*/
|
||||
|
||||
KOSAPI int _ksys_center_mouse()
|
||||
{
|
||||
int a;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(a)
|
||||
: "a"(18), "b"(15));
|
||||
return a;
|
||||
}
|
||||
|
||||
/*========= Function 18, subfunction 16 - get size of free RAM. ========*/
|
||||
|
||||
KOSAPI size_t _ksys_get_ram_size(void)
|
||||
@@ -901,19 +843,6 @@ KOSAPI uint32_t _ksys_set_mouse_settings(ksys_mouse_settings_t settings, uint32_
|
||||
|
||||
#define _ksys_set_mouse_pos(X, Y) _ksys_set_mouse_settings(KSYS_MOUSE_SET_POS, X * 65536 + Y)
|
||||
|
||||
/*===================== Function 18, subfunction 20 ====================*/
|
||||
|
||||
KOSAPI int _ksys_get_memory_info(ksys_memory_info_t* info)
|
||||
{
|
||||
int total;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(total)
|
||||
: "a"(18), "b"(20), "c"(info)
|
||||
: "memory");
|
||||
return total;
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 21 ====================*/
|
||||
/*=====Get the slot number of the process / thread by identifier.. =====*/
|
||||
|
||||
@@ -927,216 +856,6 @@ KOSAPI int _ksys_get_thread_slot(int PID)
|
||||
return val;
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 22 ====================*/
|
||||
|
||||
typedef enum KSYS_WIN_REMOTE_CONTROL {
|
||||
WIN_MINIMIZE_BY_SLOT = 0,
|
||||
WIN_MINIMIZE_BY_PID = 1,
|
||||
WIN_RESTORE_BY_SLOT = 2,
|
||||
WIN_RESTORE_BY_PID = 3
|
||||
} ksys_win_remote_control_t;
|
||||
|
||||
KOSAPI int _ksys_window_remote_control(ksys_win_remote_control_t type, uint32_t param)
|
||||
{
|
||||
int result;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(result)
|
||||
: "a"(18), "b"(22), "c"(type), "d"(param));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 23 ====================*/
|
||||
|
||||
KOSAPI int _ksys_minimize_all_windows()
|
||||
{
|
||||
int count;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(count)
|
||||
: "a"(18), "b"(23));
|
||||
return count;
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 24 ====================*/
|
||||
|
||||
KOSAPI void _ksys_set_draw_limits(unsigned int x, unsigned int y)
|
||||
{
|
||||
asm_inline(
|
||||
"int $0x40" ::"a"(18), "b"(24), "c"(x), "d"(y));
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 25 ====================*/
|
||||
|
||||
typedef enum KSYS_ZPOS {
|
||||
KSYS_ZPOS_DESKTOP = -2,
|
||||
KSYS_ZPOS_ALWAYS_BACK = -1,
|
||||
KSYS_ZPOS_NORMAL = 0,
|
||||
KSYS_ZPOS_ALWAYS_TOP = 1
|
||||
} ksys_zpos_t;
|
||||
|
||||
/*=========== Function 18, subfunction 25, subsubfunction 1 ============*/
|
||||
|
||||
KOSAPI ksys_zpos_t _ksys_get_window_zposition(int32_t pid)
|
||||
{
|
||||
ksys_zpos_t result_eax;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(result_eax)
|
||||
: "a"(18), "b"(25), "c"(1), "d"(pid));
|
||||
|
||||
return result_eax;
|
||||
}
|
||||
|
||||
/*=========== Function 18, subfunction 25, subsubfunction 2 ============*/
|
||||
|
||||
KOSAPI int _ksys_set_window_zposition(int32_t pid, ksys_zpos_t position)
|
||||
{
|
||||
int err;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(18), "b"(25), "c"(2), "d"(pid), "S"(position));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*==================== Function 21, subfunction 2 =====================*/
|
||||
|
||||
typedef enum KSYS_KEYBOARD_LAYOUT {
|
||||
KSYS_KEYBOARD_LAYOUT_NORMAL = 1,
|
||||
KSYS_KEYBOARD_LAYOUT_SHIFT = 2,
|
||||
KSYS_KEYBOARD_LAYOUT_ALT = 3
|
||||
} ksys_keyboard_layout_t;
|
||||
|
||||
KOSAPI int _ksys_set_keyboard_layout(ksys_keyboard_layout_t mode, char* table)
|
||||
{
|
||||
int err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(2), "c"(mode), "d"(table));
|
||||
return err;
|
||||
}
|
||||
|
||||
typedef enum KSYS_LANG {
|
||||
KSYS_LANG_ENG = 1,
|
||||
KSYS_LANG_FI = 2,
|
||||
KSYS_LANG_GER = 3,
|
||||
KSYS_LANG_RU = 4
|
||||
} ksys_lang_t;
|
||||
|
||||
KOSAPI int _ksys_set_keyboard_lang(ksys_lang_t lang)
|
||||
{
|
||||
int err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(2), "c"(9), "d"(lang));
|
||||
return err;
|
||||
}
|
||||
|
||||
/*==================== Function 21, subfunction 5 =====================*/
|
||||
|
||||
KOSAPI int _ksys_set_lang(ksys_lang_t lang)
|
||||
{
|
||||
int err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(5), "c"(lang));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*==================== Function 21, subfunction 11 =====================*/
|
||||
|
||||
KOSAPI int _ksys_allow_HD(int param)
|
||||
{
|
||||
int err;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(11), "c"(param));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*==================== Function 21, subfunction 12 =====================*/
|
||||
|
||||
KOSAPI int _ksys_allow_PCI(int param)
|
||||
{
|
||||
int err;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(12), "c"(param));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
typedef enum KSYS_SET_TIME_ERR {
|
||||
KSYS_SET_TIME_OK = 0,
|
||||
KSYS_SET_TIME_WRONG_PARAM = 1,
|
||||
KSYS_SET_TIME_CMOS = 2
|
||||
} ksys_set_time_err;
|
||||
|
||||
/*============================ Function 22 ============================*/
|
||||
|
||||
KOSAPI ksys_set_time_err _ksys_set_time(ksys_time_bcd_t time)
|
||||
{
|
||||
ksys_set_time_err err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(22), "b"(0), "c"(time));
|
||||
}
|
||||
|
||||
KOSAPI ksys_set_time_err _ksys_set_date(ksys_date_bcd_t date)
|
||||
{
|
||||
ksys_set_time_err err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(22), "b"(1), "c"(date));
|
||||
}
|
||||
|
||||
/*========= Function 26, subfunction 2 - get keyboard layout. ==========*/
|
||||
|
||||
KOSAPI uint32_t _ksys_keyboard_layout(ksys_keyboard_layout_t layout, unsigned char* buf)
|
||||
{
|
||||
asm_inline("int $0x40" ::"a"(26), "b"(2), "c"(layout), "d"(buf) : "memory");
|
||||
}
|
||||
|
||||
KOSAPI ksys_lang_t _ksys_get_keyboard_lang()
|
||||
{
|
||||
ksys_lang_t lang;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(lang)
|
||||
: "a"(26), "b"(2), "c"(9));
|
||||
return lang;
|
||||
}
|
||||
|
||||
/*======= Function 26, subfunction 5 - get the system language. ========*/
|
||||
|
||||
KOSAPI ksys_lang_t _ksys_get_lang()
|
||||
{
|
||||
ksys_lang_t lang;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(lang)
|
||||
: "a"(26), "b"(5));
|
||||
|
||||
return lang;
|
||||
}
|
||||
|
||||
/*============= Function 23 - wait for event with timeout. =============*/
|
||||
|
||||
KOSAPI uint32_t _ksys_wait_event_timeout(uint32_t timeout)
|
||||
|
||||
@@ -25,6 +25,7 @@ img_files = {
|
||||
{"MACROS.INC", SRC_PROGS .. "/macros.inc"},
|
||||
-- {"CONFIG.INC", SRC_PROGS .. "/config.inc"},
|
||||
{"STRUCT.INC", SRC_PROGS .. "/struct.inc"},
|
||||
{"FB2READ", "common/fb2read"},
|
||||
{"ALLGAMES", "common/allgames"},
|
||||
{"HOME.PNG", "common/wallpapers/T_Home.png"},
|
||||
{"ICONS32.PNG", "common/icons32.png"},
|
||||
@@ -532,7 +533,6 @@ tup.append_table(img_files, {
|
||||
{"MEDIA/MP3INFO", VAR_PROGS .. "/media/mp3info/mp3info"},
|
||||
{"MEDIA/PALITRA", VAR_PROGS .. "/media/palitra/trunk/palitra"},
|
||||
{"MEDIA/PIANO", VAR_PROGS .. "/media/piano/piano"},
|
||||
{"MEDIA/PIANO.MAP", VAR_PROGS .. "/media/piano/piano.map"},
|
||||
{"MEDIA/STARTMUS", VAR_PROGS .. "/media/startmus/trunk/STARTMUS"},
|
||||
{"NETWORK/PING", VAR_PROGS .. "/network/ping/ping"},
|
||||
{"NETWORK/NETCFG", VAR_PROGS .. "/network/netcfg/netcfg"},
|
||||
@@ -735,6 +735,7 @@ tup.append_table(extra_files, {
|
||||
{"kolibrios/develop/TinyBasic/TinyBasic", VAR_PROGS .. "/develop/tinybasic-1.0.4/tinybasic"},
|
||||
{"kolibrios/develop/TinyBasic/bas/", SRC_PROGS .. "/develop/tinybasic-1.0.4/bas/*"},
|
||||
{"kolibrios/develop/TinyBasic/TinyBasic.man", SRC_PROGS .. "/develop/tinybasic-1.0.4/doc/tinybasic.man"},
|
||||
-- {"kolibrios/utils/teatool", VAR_PROGS .. "/other/TEAtool/teatool"},
|
||||
{"kolibrios/utils/passwordgen", VAR_PROGS .. "/other/PasswordGen/passwordgen"},
|
||||
{"kolibrios/utils/kruler", VAR_PROGS .. "/other/kruler/kruler"},
|
||||
{"kolibrios/media/qr_tool", SRC_PROGS .. "/media/qr_tool/qr_tool"},
|
||||
@@ -748,7 +749,6 @@ end -- tup.getconfig('NO_TCC') ~= 'full'
|
||||
if tup.getconfig('NO_OB07') ~= 'full' then
|
||||
tup.append_table(img_files, {
|
||||
{"DEVELOP/CEDIT", VAR_PROGS .. "/develop/cedit/cedit"},
|
||||
{"FB2READ", VAR_PROGS .. "/other/fb2reader/fb2read"},
|
||||
})
|
||||
end -- tup.getconfig('NO_OB07') ~= 'full'
|
||||
|
||||
@@ -758,6 +758,7 @@ tup.append_table(img_files, {
|
||||
{"GAMES/REVERSI", VAR_PROGS .. "/games/reversi/reversi"},
|
||||
{"LIB/BASE64.OBJ", VAR_PROGS .. "/develop/libraries/base64/base64.obj"},
|
||||
{"LIB/ICONV.OBJ", VAR_PROGS .. "/develop/libraries/iconv/iconv.obj"},
|
||||
-- {"LIB/MTAR.OBJ", VAR_PROGS .. "/develop/libraries/microtar/mtar.obj"},
|
||||
})
|
||||
tup.append_table(extra_files, {
|
||||
-- {"kolibrios/3D/cubeline", VAR_PROGS .. "/demos/cubeline/trunk/cubeline"},
|
||||
|
||||
BIN
data/common/fb2read
Normal file
BIN
data/common/fb2read
Normal file
Binary file not shown.
@@ -1985,7 +1985,7 @@ path db 'HD0/1',0
|
||||
подфункция 2 функции 15.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_BACKGROUND_GET (39)
|
||||
eax - SF_BACKGROUND_GET_RECT (39)
|
||||
======================================================================
|
||||
== Функция 39, подфункция 3 - получить прямоугольную область фона =
|
||||
======================================================================
|
||||
@@ -2169,7 +2169,7 @@ path db 'HD0/1',0
|
||||
* ebx = 2 - номер подфункции
|
||||
* ecx = указатель на таблицу цветов
|
||||
* edx = размер таблицы цветов
|
||||
(до 192 байт; 40 байт для базовой структуры)
|
||||
(должен быть 40 байт для будущей совместимости)
|
||||
Формат таблицы цветов указан в описании подфункции 3.
|
||||
Возвращаемое значение:
|
||||
* функция не возвращает значения
|
||||
@@ -2196,33 +2196,32 @@ path db 'HD0/1',0
|
||||
* ecx = указатель на буфер размером edx байт,
|
||||
куда будет записана таблица
|
||||
* edx = размер таблицы цветов
|
||||
(до 192 байт; 40 байт для базовой структуры)
|
||||
(должен быть 40 байт для будущей совместимости)
|
||||
Возвращаемое значение:
|
||||
* функция не возвращает значения
|
||||
Формат таблицы цветов: каждый элемент -
|
||||
dword-значение цвета 0x00RRGGBB
|
||||
* +0: dword: frame
|
||||
* +4: dword: grab
|
||||
* +0: dword: none - зарезервировано
|
||||
* +4: dword: none - зарезервировано
|
||||
* +8: dword: work_dark - темный цвет рабочей области для придания
|
||||
объемна элементам интерфейса
|
||||
* +12 = +0xC: dword: work_light - светлый цвет рабочей области для
|
||||
придания объемна элементам интерфейса
|
||||
* +16 = +0x10: dword: grab_text - цвет текста на заголовке
|
||||
* +20 = +0x14: dword: work - цвет рабочей области
|
||||
* +24 = +0x18: dword: work_button - цвет кнопки в рабочей области
|
||||
* +28 = +0x1C: dword: work_button_text - цвет текста на кнопке
|
||||
* +24 = +0x18: dword: button - цвет кнопки в рабочей области
|
||||
* +28 = +0x1C: dword: button_text - цвет текста на кнопке
|
||||
в рабочей области
|
||||
* +32 = +0x20: dword: work_text - цвет текста в рабочей области
|
||||
* +36 = +0x24: dword: graph - цвет графики в рабочей области
|
||||
Замечания:
|
||||
* Структура таблицы цветов описана в стандартном включаемом файле
|
||||
macros.inc под названием system_colors; например, можно писать:
|
||||
sc system_colors ; объявление переменной
|
||||
... ; вызов описываемой функции с ecx = sc
|
||||
mov ecx, [sc.work_button_text] ; устанавливаем цвет текста
|
||||
; на кнопке в рабочей области
|
||||
* Таблица может быть больше (до 192 байт); дополнительные поля
|
||||
копируются как есть и интерпретируются скинами.
|
||||
sc system_colors ; объявление переменной
|
||||
... ; где-то надо вызвать
|
||||
; описываемую функцию с ecx=sc
|
||||
mov ecx, [sc.button_text] ; читаем цвет текста
|
||||
; на кнопке в рабочей области
|
||||
* Использование/неиспользование этих цветов - дело исключительно
|
||||
самой программы. Для использования нужно просто при вызове функций
|
||||
рисования указывать цвет, взятый из этой таблицы.
|
||||
@@ -2492,7 +2491,6 @@ dword-значение цвета 0x00RRGGBB
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_SET_WINDOW_SHAPE (50)
|
||||
|
||||
======================================================================
|
||||
===================== Функция 51, подфункция 1 =======================
|
||||
========================== Создать поток =============================
|
||||
@@ -2507,19 +2505,16 @@ dword-значение цвета 0x00RRGGBB
|
||||
* иначе eax = TID - идентификатор потока
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_CREATE_THREAD (51) /
|
||||
ebx - SSF_CREATE_THREAD (1), SSF_GET_CURR_THREAD_SLOT (2),
|
||||
SSF_GET_THREAD_PRIORITY (3), SSF_SET_THREAD_PRIORITY (4)
|
||||
|
||||
eax - SF_CREATE_THREAD (51)
|
||||
======================================================================
|
||||
===================== Функция 51, подфункция 2 =======================
|
||||
============= Получить номер слота текущего потока ===================
|
||||
=================== Получить номер слота потока ======================
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 51 - номер функции
|
||||
* ebx = 2 - номер подфункции
|
||||
Возвращаемое значение:
|
||||
* eax = номер слота текущего потока
|
||||
* eax = номер слота потока
|
||||
|
||||
======================================================================
|
||||
===================== Функция 51, подфункция 3 =======================
|
||||
@@ -2760,10 +2755,10 @@ IPC применяется для посылок сообщений от одн
|
||||
Программе доступны данные графического экрана (область памяти, которая
|
||||
собственно и отображает содержимое экрана) напрямую без вызовов
|
||||
системных функций через селектор gs:
|
||||
mov eax, [gs:0]
|
||||
mov eax, [gs:0]
|
||||
поместит в eax первый dword буфера, содержащий информацию о цвете
|
||||
левой верхней точки (и, возможно, цвета нескольких следующих).
|
||||
mov [gs:0], eax
|
||||
mov [gs:0], eax
|
||||
при работе в режимах VESA c LFB
|
||||
установит цвет левой верхней точки
|
||||
(и возможно, цвета нескольких следующих).
|
||||
@@ -3361,7 +3356,6 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_SYS_MISC (68)
|
||||
ebx - SSF_MEM_FREE (13)
|
||||
|
||||
======================================================================
|
||||
====================== Функция 68, подфункция 14 =====================
|
||||
====== Ожидать получения сигнала от других приложений/драйверов. =====
|
||||
@@ -3374,16 +3368,12 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
* eax разрушается
|
||||
* буфер, на который указывает ecx, содержит следующую информацию:
|
||||
* +0: dword: идентификатор последующих данных сигнала
|
||||
* +4: 5 dword: данные принятого сигнала, формат которых
|
||||
* +4: данные принятого сигнала (20 байт), формат которых
|
||||
определяется первым dword-ом
|
||||
Замечания:
|
||||
* Бесконечно ожидает любое событие в очереди событий текущего потока.
|
||||
* Сбрасывает байт приоритета в буфере.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_SYS_MISC (68)
|
||||
ebx - SSF_WAIT_SIGNAL (14)
|
||||
|
||||
======================================================================
|
||||
=========== Функция 68, подфункция 16 - загрузить драйвер. ===========
|
||||
======================================================================
|
||||
@@ -3392,20 +3382,19 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
* ebx = 16 - номер подфункции
|
||||
* ecx = указатель на ASCIIZ-строку с именем драйвера
|
||||
Возвращаемое значение:
|
||||
* eax = хэндл драйвера
|
||||
0 при ошибке
|
||||
* eax = 0 - неудача
|
||||
* иначе eax = хэндл драйвера
|
||||
Замечания:
|
||||
* Если драйвер ещё не загружен, он загружается;
|
||||
если драйвер уже загружен, ничего не меняется.
|
||||
* Имя драйвера чувствительно к регистру символов.
|
||||
Максимальная длина имени - 16 символов, включая завершающий
|
||||
нулевой символ, остальные символы игнорируются.
|
||||
* Драйвер с именем "ABC" загружается из файла /sys/drivers/ABC.sys.
|
||||
* Драйвер с именем ABC загружается из файла /sys/drivers/ABC.sys.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_SYS_MISC (68)
|
||||
ebx - SSF_LOAD_DRIVER (16)
|
||||
|
||||
======================================================================
|
||||
========== Функция 68, подфункция 17 - управление драйвером. =========
|
||||
======================================================================
|
||||
@@ -3416,21 +3405,19 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
* +0: dword: хэндл драйвера
|
||||
* +4: dword: код функции драйвера
|
||||
* +8: dword: указатель на входные данные
|
||||
* +12 = +0x0C: dword: размер входных данных
|
||||
* +12 = +0xC: dword: размер входных данных
|
||||
* +16 = +0x10: dword: указатель на выходные данные
|
||||
* +20 = +0x14: dword: размер выходных данных
|
||||
Возвращаемое значение:
|
||||
* eax = определяется драйвером
|
||||
-1 при ошибке
|
||||
Замечания:
|
||||
* Коды функций и структура входных/выходных данных
|
||||
определяются драйвером.
|
||||
* Хэндл драйвера необходимо предварительно получить подфункцией 16.
|
||||
* Предварительно должен быть получен хэндл драйвера подфункцией 16.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_SYS_MISC (68)
|
||||
ebx - SSF_CONTROL_DRIVER (17)
|
||||
|
||||
======================================================================
|
||||
== Функция 68, подфункция 18 - загрузить DLL с указанием кодировки. ==
|
||||
======================================================================
|
||||
@@ -3495,7 +3482,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
Параметры:
|
||||
* eax = 68 - номер функции
|
||||
* ebx = 21 - номер подфункции
|
||||
* ecx = указатель на ASCIIZ-строку с путем к файлу драйвера
|
||||
* ecx = указатель на ASCIIZ-строку с именем драйвера
|
||||
* edx = указатель на командную строку
|
||||
Возвращаемое значение:
|
||||
* eax = 0 - неудача
|
||||
@@ -3687,40 +3674,22 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
* функция загружает и, при необходимости, распаковывает файл (kunpack)
|
||||
|
||||
======================================================================
|
||||
======= Функция 68, подфункция 29 - выделить кольцевую память. =======
|
||||
======== Функция 68, подфункция 29 - allocate ring memory. =========
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 68 - номер функции
|
||||
* ebx = 29 - номер подфункции
|
||||
* ecx = требуемый размер в байтах
|
||||
Возвращаемое значение:
|
||||
* eax = 0 - неудача
|
||||
* eax = указатель на выделенную кольцевую память
|
||||
Замечания:
|
||||
* Запрошенный размер должен быть кратен размеру страницы (4 Кб).
|
||||
* Память выделяется так, что доступ за пределами буфера приводит
|
||||
к чтению/записи в его начало.
|
||||
Parameters:
|
||||
* eax = 68 - function number
|
||||
* ebx = 29 - subfunction number
|
||||
* ecx = required size in bytes
|
||||
Returned value:
|
||||
* eax = 0 - failed
|
||||
* eax = pointer to the allocated ring
|
||||
Remarks:
|
||||
* The requested size must be an exact multiple of pagesize (4 Kb)
|
||||
* The function allocates memory in such a way that you can read and
|
||||
write beyond the size of the allocated memory and will reach the
|
||||
beginning of the buffer again.
|
||||
|
||||
|
||||
======================================================================
|
||||
=========== Функция 68, подфункция 30 - выгрузить драйвер. ===========
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 68 - номер функции
|
||||
* ebx = 30 - номер подфункции
|
||||
* ecx = указатель на структуру SRV (хэндл драйвера)
|
||||
* edx = указатель на командную строку (может быть 0)
|
||||
Возвращаемое значение:
|
||||
* eax = -1 - неверные параметры
|
||||
* eax = -2 - ошибка при освобождении памяти драйвера
|
||||
* иначе eax = указатель на следующую структуру SRV (бывший SRV.fd)
|
||||
Замечания:
|
||||
* Перед выгрузкой вызывается точка входа драйвера с DRV_EXIT.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_SYS_MISC (68)
|
||||
ebx - SSF_UNLOAD_DRIVER (30)
|
||||
|
||||
======================================================================
|
||||
======== Функция 68, подфункция 31 - получить данные драйвера. =======
|
||||
======================================================================
|
||||
@@ -3819,7 +3788,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
и при поступлении нового сообщения система будет ждать.
|
||||
Для синхронизации обрамляйте всю работу с буфером операциями
|
||||
блокировки/разблокировки
|
||||
neg [bufsize]
|
||||
neg [bufsize]
|
||||
* Данные в буфере трактуются как массив элементов переменной длины -
|
||||
сообщений. Формат сообщения указан в общем описании.
|
||||
|
||||
@@ -4558,7 +4527,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_NETWORK_GET (74)
|
||||
bl - SSF_DEVICE_COUNT (-1)
|
||||
bl - SSF_DEVICE_COUNT (255)
|
||||
======================================================================
|
||||
==== Функция 74, подфункция 0, Получить тип сетевого устройства. =====
|
||||
======================================================================
|
||||
@@ -4754,11 +4723,10 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
Возвращаемое значение:
|
||||
* eax = число пакетов, полученных с ошибкой с момента запуска
|
||||
устройства, -1 при ошибке
|
||||
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_NETWORK_GET (74)
|
||||
bl - SSF_RX_PACKET_ERROR_COUNT (14)
|
||||
|
||||
======================================================================
|
||||
== Функция 74.15, Получить число пакетов отброшенных при получении. ==
|
||||
======================================================================
|
||||
@@ -4772,7 +4740,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_NETWORK_GET (74)
|
||||
bl - SSF_RX_PACKET_DROP_COUNT (15)
|
||||
bl - SSF_RX_PACKET_DROP_COUNT (12)
|
||||
======================================================================
|
||||
=== Функция 74.16, Получить число пакетов утерянных при получении. ===
|
||||
======================================================================
|
||||
@@ -5022,39 +4990,13 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_NETWORK_PROTOCOL (76)
|
||||
ebx - SSF_ETHERNET_READ_MAC (0x0000)
|
||||
ebx - SSF_IP4_PACKETS_SENT (0x10000)
|
||||
ebx - SSF_IP4_PACKETS_RECEIVED (0x10001)
|
||||
ebx - SSF_IP4_READ_IP (0x10002)
|
||||
ebx - SSF_IP4_WRITE_IP (0x10003)
|
||||
ebx - SSF_IP4_READ_DNS (0x10004)
|
||||
ebx - SSF_IP4_WRITE_DNS (0x10005)
|
||||
ebx - SSF_IP4_READ_SUBNET (0x10006)
|
||||
ebx - SSF_IP4_WRITE_SUBNET (0x10007)
|
||||
ebx - SSF_IP4_READ_GATEWAY (0x10008)
|
||||
ebx - SSF_IP4_WRITE_GATEWAY (0x10009)
|
||||
ebx - SSF_ICMP_PACKETS_SENT (0x20000)
|
||||
ebx - SSF_ICMP_PACKETS_RECEIVED (0x20001)
|
||||
ebx - SSF_ICMP_ECHO_REPLY (0x20003)
|
||||
ebx - SSF_UDP_PACKETS_SENT (0x30000)
|
||||
ebx - SSF_UDP_PACKETS_RECEIVED (0x30001)
|
||||
ebx - SSF_TCP_PACKETS_SENT (0x40000)
|
||||
ebx - SSF_TCP_PACKETS_RECEIVED (0x40001)
|
||||
ebx - SSF_ARP_PACKETS_SENT (0x50000)
|
||||
ebx - SSF_ARP_PACKETS_RECEIVED (0x50001)
|
||||
ebx - SSF_ARP_GET_ENTRY_COUNT (0x50002)
|
||||
ebx - SSF_ARP_READ_ENTRY (0x50003)
|
||||
ebx - SSF_ARP_ADD_STATIC_ENTRY (0x50004)
|
||||
ebx - SSF_ARP_DEL_ENTRY (0x50005)
|
||||
ebx - SSF_ARP_SEND_ANNOUNCE (0x50006)
|
||||
ebx - SSF_ARP_CONFLICTS_COUNT (0x50007)
|
||||
======================================================================
|
||||
============= Функция 77, подфункция 0, Создать фьютекс. =============
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 77 - номер функции
|
||||
* ebx = 0 - номер подфункции
|
||||
* ecx = контрольное значение фьютекса (dword)
|
||||
* ecx = указатель на контрольное значение фьютекса (dword)
|
||||
Возвращаемое значение:
|
||||
* eax = дескриптор фьютекса, 0 при ошибке
|
||||
|
||||
@@ -5083,12 +5025,11 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
* eax = 77 - номер функции
|
||||
* ebx = 2 - номер подфункции
|
||||
* ecx = дескриптор фьютекса
|
||||
* edx = контрольное значение фьютекса (dword)
|
||||
* edx = контрольное значение
|
||||
* esi = таймаут в сотых секунды, 0 - ждать бесконечно
|
||||
Возвращаемое значение:
|
||||
* eax = 0 - успешно,
|
||||
-1 - таймаут,
|
||||
-2 - контрольное значение фьютекса не соответствует
|
||||
* eax = 0 - успешно, -1 - таймаут,
|
||||
-2 - контрольное значение не соответствует
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
@@ -5108,11 +5049,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
eax - SF_FUTEX (77)
|
||||
ebx - SSF_WAKE (3)
|
||||
======================================================================
|
||||
Замечания:
|
||||
* Подфункции 4-7 зарезервированы и сейчас возвращают -1.
|
||||
* Подфункции 8, 9 и 12 не реализованы и возвращают -EBADF (-9).
|
||||
======================================================================
|
||||
=========== Функция 77, подфункция 10, Прочитать из файла. ===========
|
||||
======= Функция 77, подфункция 10, Прочитать из файла в буфер. =======
|
||||
======================================================================
|
||||
Параметры:
|
||||
* eax = 77 - номер функции
|
||||
@@ -5122,15 +5059,10 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
* esi = сколько байт прочитать
|
||||
Возвращаемое значение:
|
||||
* eax = количество прочитанных байт
|
||||
0 при EOF
|
||||
-EBADF (-9) при ошибке
|
||||
Замечания:
|
||||
* Поддерживаются только pipe-дескрипторы.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
ebx - SSF_FILE_READ (10)
|
||||
|
||||
ebx - ...
|
||||
======================================================================
|
||||
======== Функция 77, подфункция 11, Записать из буфера в файл. =======
|
||||
======================================================================
|
||||
@@ -5138,19 +5070,14 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
* eax = 77 - номер функции
|
||||
* ebx = 11 - номер подфункции
|
||||
* ecx = дескриптор файла
|
||||
* edx = указатель на буфер, откуда брать данные для записи
|
||||
* edx = указатель на буфер, откуда брать данные для записи
|
||||
* esi = сколько байт записать
|
||||
Возвращаемое значение:
|
||||
* eax = количество записанных байт
|
||||
-EBADF (-9) при ошибке
|
||||
-EPIPE (-32) если нет читателей
|
||||
Замечания:
|
||||
* Поддерживаются только pipe-дескрипторы.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
ebx - SSF_FILE_WRITE (11)
|
||||
|
||||
ebx - ...
|
||||
======================================================================
|
||||
=========== Функция 77, подфункция 13, Создать новый pipe. ===========
|
||||
======================================================================
|
||||
@@ -5162,20 +5089,15 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
* eax = 77 - номер функции
|
||||
* ebx = 13 - номер подфункции
|
||||
* ecx = адрес pipefd
|
||||
* edx = флаги. Разрешен только O_CLOEXEC (0x40000).
|
||||
Любые другие биты приводят к -EINVAL (-11).
|
||||
* edx = флаги. На данный момент если поднят O_CLOEXEC (0x40000), то
|
||||
сисфункция завершится с ошибкой. Поэтому в качестве флагов можно
|
||||
передать просто 0.
|
||||
Возвращаемое значение:
|
||||
* eax = 0 если успех,
|
||||
иначе отрицательный код ошибки:
|
||||
-EINVAL (-11), -EFAULT (-14), -ENFILE (-23), -EMFILE (-24)
|
||||
Примечания:
|
||||
* В случае успеха pipefd[0] является дескриптором чтения, а pipefd[1]
|
||||
- дескриптором записи.
|
||||
* eax = 0 если успех, иначе ошибка.
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
ebx - SSF_PIPE_CREATE (13)
|
||||
|
||||
ebx - ...
|
||||
======================================================================
|
||||
========== Функция -1 - завершить выполнение потока/процесса =========
|
||||
======================================================================
|
||||
@@ -5193,7 +5115,6 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
||||
|
||||
---------------------- Константы для регистров: ----------------------
|
||||
eax - SF_TERMINATE_PROCESS (-1)
|
||||
|
||||
======================================================================
|
||||
=== Функция 80 - работа с файловой системой с указанием кодировки. ===
|
||||
======================================================================
|
||||
|
||||
@@ -1972,7 +1972,7 @@ Remarks:
|
||||
subfunction 2 of function 15.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_BACKGROUND_GET (39)
|
||||
eax - SF_BACKGROUND_GET_RECT (39)
|
||||
======================================================================
|
||||
== Function 39, subfunction 3 - get rect from the background image. =
|
||||
======================================================================
|
||||
@@ -2152,7 +2152,7 @@ Parameters:
|
||||
* ebx = 2 - subfunction number
|
||||
* ecx = pointer to the color table
|
||||
* edx = size of the color table
|
||||
(up to 192 bytes; 40 bytes for the base structure)
|
||||
(must be 40 bytes for future compatibility)
|
||||
Format of the color table is shown in description of subfunction 3.
|
||||
Returned value:
|
||||
* function does not return value
|
||||
@@ -2179,21 +2179,21 @@ Parameters:
|
||||
* ecx = pointer to the buffer with size edx bytes,
|
||||
where table will be written
|
||||
* edx = size of color table
|
||||
(up to 192 bytes; 40 bytes for the base structure)
|
||||
(must be 40 bytes for future compatibility)
|
||||
Returned value:
|
||||
* function does not return value
|
||||
Format of the color table:
|
||||
each item is dword-value for color 0x00RRGGBB
|
||||
* +0: dword: frame
|
||||
* +4: dword: grab
|
||||
* +0: dword: none - reserved
|
||||
* +4: dword: none - reserved
|
||||
* +8: dword: work_dark - dark color of working area
|
||||
used to give a user 3D-like feelings about interface elements
|
||||
* +12 = +0xC: dword: work_light - light color of working area
|
||||
used to give a user 3D-like feelings about interface elements
|
||||
* +16 = +0x10: dword: grab_text - color of text on header
|
||||
* +20 = +0x14: dword: work - color of working area
|
||||
* +24 = +0x18: dword: work_button - color of button in working area
|
||||
* +28 = +0x1C: dword: work_button_text - color of text on button
|
||||
* +24 = +0x18: dword: button - color of button in working area
|
||||
* +28 = +0x1C: dword: button_text - color of text on button
|
||||
in working area
|
||||
* +32 = +0x20: dword: work_text - color of text in working area
|
||||
* +36 = +0x24: dword: graph - color of graphics in working area
|
||||
@@ -2206,8 +2206,6 @@ Remarks:
|
||||
; this function with ecx=sc
|
||||
mov ecx, [sc.work_button_text] ; read text color on
|
||||
; button in working area
|
||||
* The table may be longer (up to 192 bytes); extra fields are copied
|
||||
as-is and are interpreted by skins.
|
||||
* A program itself decides to use or not to use color table.
|
||||
For usage program must simply at calls to drawing functions select
|
||||
color taken from the table.
|
||||
@@ -2480,11 +2478,11 @@ Remarks:
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_SET_WINDOW_SHAPE (50)
|
||||
======================================================================
|
||||
============= Function 51, subfunction 1 - create thread. ============
|
||||
==================== Function 51 - create thread. ====================
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 51 - function number
|
||||
* ebx = 1 - subfunction number
|
||||
* ebx = 1 - unique subfunction
|
||||
* ecx = address of thread entry point (starting eip)
|
||||
* edx = pointer to thread stack (starting esp)
|
||||
Returned value:
|
||||
@@ -2493,49 +2491,6 @@ Returned value:
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_CREATE_THREAD (51)
|
||||
ebx - SSF_CREATE_THREAD (1), SSF_GET_CURR_THREAD_SLOT (2),
|
||||
SSF_GET_THREAD_PRIORITY (3), SSF_SET_THREAD_PRIORITY (4)
|
||||
======================================================================
|
||||
================== Function 51, subfunction 2 ========================
|
||||
================== Get current thread slot number ====================
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 51 - function number
|
||||
* ebx = 2 - subfunction number
|
||||
Returned value:
|
||||
* eax = slot number of the current thread
|
||||
|
||||
======================================================================
|
||||
================== Function 51, subfunction 3 ========================
|
||||
===================== Get thread priority ============================
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 51 - function number
|
||||
* ebx = 3 - subfunction number
|
||||
* ecx = slot number of the thread or -1 (current thread)
|
||||
Returned value:
|
||||
* eax = -1 - error (invalid slot number or thread terminated)
|
||||
* otherwise eax = thread priority
|
||||
Remarks:
|
||||
* Priority range is 0..255.
|
||||
0 is the highest priority and is set by default at creation.
|
||||
|
||||
======================================================================
|
||||
================== Function 51, subfunction 4 ========================
|
||||
===================== Set thread priority ============================
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 51 - function number
|
||||
* ebx = 4 - subfunction number
|
||||
* ecx = slot number of the thread or -1 (current thread)
|
||||
* edx = new thread priority
|
||||
Returned value:
|
||||
* eax = -1 - error (invalid slot number or thread terminated)
|
||||
* otherwise eax = previous thread priority
|
||||
Remarks:
|
||||
* Priority range is 0..255.
|
||||
0 is the highest priority and is set by default at creation.
|
||||
|
||||
======================================================================
|
||||
==================== Function 54, subfunction 0 ======================
|
||||
============== Get the number of slots in the clipboard. =============
|
||||
@@ -3334,63 +3289,61 @@ Remarks:
|
||||
ebx - SSF_MEM_FREE (13)
|
||||
======================================================================
|
||||
===================== Function 68, subfunction 14 ====================
|
||||
======= Wait for a signal from other applications/drivers. ===========
|
||||
============ Wait for signal from another program/driver. ============
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 68 - function number
|
||||
* ebx = 14 - subfunction number
|
||||
* ecx = pointer to data buffer (6 dword = 24 bytes)
|
||||
* ecx = pointer to the buffer for information (24 bytes)
|
||||
Returned value:
|
||||
* eax is destroyed
|
||||
* buffer pointed to by ecx contains the following information:
|
||||
* +0: dword: EVENT.code (identifier of following data)
|
||||
* +4: 5 dword: EVENT.data, format depends on EVENT.code
|
||||
Remarks:
|
||||
* Waits indefinitely for any event in the current thread event queue.
|
||||
* The priority byte in the buffer is cleared by the kernel.
|
||||
* +0: dword: identifier for following data of signal
|
||||
* +4: dword: data of signal (20 bytes), format of which is defined
|
||||
by the first dword
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_SYS_MISC (68)
|
||||
ebx - SSF_WAIT_SIGNAL (14)
|
||||
======================================================================
|
||||
=========== Function 68, subfunction 16 - load driver. ===============
|
||||
============= Function 68, subfunction 16 - load driver. =============
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 68 - function number
|
||||
* ebx = 16 - subfunction number
|
||||
* ecx = pointer to ASCIIZ-string with driver name
|
||||
Returned value:
|
||||
* eax = driver handle, 0 on error
|
||||
* eax = 0 - failed
|
||||
* otherwise eax = driver handle
|
||||
Remarks:
|
||||
* If the driver is not loaded yet, it is loaded;
|
||||
if the driver is already loaded, nothing changes.
|
||||
* If the driver was not loaded yet, it is loaded;
|
||||
if the driver was loaded yet, nothing happens.
|
||||
* Driver name is case-sensitive.
|
||||
Maximum length of the name is 16 characters, including
|
||||
terminating null character, the rest is ignored.
|
||||
* Driver with name "ABC" is loaded from /sys/drivers/ABC.sys.
|
||||
* Driver ABC is loaded from file /sys/drivers/ABC.sys.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_SYS_MISC (68)
|
||||
ebx - SSF_LOAD_DRIVER (16)
|
||||
======================================================================
|
||||
========== Function 68, subfunction 17 - control driver. =============
|
||||
============ Function 68, subfunction 17 - driver control. ===========
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 68 - function number
|
||||
* ebx = 17 - subfunction number
|
||||
* ecx = pointer to the control structure:
|
||||
* +0: dword: driver handle
|
||||
* +4: dword: driver function code
|
||||
* +8: dword: pointer to input data
|
||||
* +12: dword: size of input data
|
||||
* +16: dword: pointer to output data
|
||||
* +20: dword: size of output data
|
||||
* +0: dword: handle of driver
|
||||
* +4: dword: code of driver function
|
||||
* +8: dword: pointer to input data
|
||||
* +12 = +0xC: dword: size of input data
|
||||
* +16 = +0x10: dword: pointer to output data
|
||||
* +20 = +0x14: dword: size of output data
|
||||
Returned value:
|
||||
* eax = determined by driver, -1 on error
|
||||
* eax = determined by driver
|
||||
Remarks:
|
||||
* Function codes and the structure of input/output data
|
||||
are defined by the driver.
|
||||
* Driver handle can be obtained by subfunction 16.
|
||||
are defined by driver.
|
||||
* Previously one must obtain driver handle by subfunction 16.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_SYS_MISC (68)
|
||||
@@ -3458,7 +3411,7 @@ Remarks:
|
||||
Parameters:
|
||||
* eax = 68 - function number
|
||||
* ebx = 21 - subfunction number
|
||||
* ecx = pointer to ASCIIZ-string with path to driver file
|
||||
* ecx = pointer to ASCIIZ-string with driver name
|
||||
* edx = pointer to command line
|
||||
Returned value:
|
||||
* eax = 0 - failed
|
||||
@@ -3663,24 +3616,9 @@ Remarks:
|
||||
write beyond the size of the allocated memory and will reach the
|
||||
beginning of the buffer again.
|
||||
|
||||
======================================================================
|
||||
=========== Function 68, subfunction 30 - unload driver. ============
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 68 - function number
|
||||
* ebx = 30 - subfunction number
|
||||
* ecx = pointer to SRV structure (driver handle)
|
||||
* edx = pointer to command line (may be 0)
|
||||
Returned value:
|
||||
* eax = -1 - invalid parameters
|
||||
* eax = -2 - error while freeing driver memory
|
||||
* otherwise eax = pointer to the next SRV structure (former SRV.fd)
|
||||
Remarks:
|
||||
* The driver entry is called with DRV_EXIT before unloading.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_SYS_MISC (68)
|
||||
ebx - SSF_UNLOAD_DRIVER (30)
|
||||
ebx - SSF_MEM_ALLOC_RING (29)
|
||||
|
||||
======================================================================
|
||||
=========== Function 68, subfunction 31 - get driver data. ===========
|
||||
@@ -3895,7 +3833,7 @@ Remarks:
|
||||
eax - SF_DEBUG (69)
|
||||
ebx - SSF_RESUME (5)
|
||||
======================================================================
|
||||
= Function 69, subfunction 6 - read from memory of debugged process. =
|
||||
= Fucntion 69, subfunction 6 - read from memory of debugged process. =
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 69 - function number
|
||||
@@ -4504,17 +4442,17 @@ Returned value:
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_BLITTER (73)
|
||||
======================================================================
|
||||
= Function 74, Subfunction -1, Get number of active network devices. =
|
||||
= Function 74, Subfunction 255, Get number of active network devices. =
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 74 - function number
|
||||
* bl = -1 - subfunction number
|
||||
* bl = 255 - subfunction number
|
||||
Returned value:
|
||||
* eax = number of active network devices
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_NETWORK_GET (74)
|
||||
bl - SSF_DEVICE_COUNT (-1)
|
||||
bl - SSF_DEVICE_COUNT (255)
|
||||
======================================================================
|
||||
======== Function 74, Subfunction 0, Get network device type. ========
|
||||
======================================================================
|
||||
@@ -4667,7 +4605,7 @@ Parameters:
|
||||
* bl = 11 - subfunction number
|
||||
* bh = device number
|
||||
Returned value:
|
||||
* eax = Number of erroneous packets transmitted since device start, -1 on error
|
||||
* eax = Number of erroneous packets received since device start, -1 on error
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_NETWORK_GET (74)
|
||||
@@ -4723,7 +4661,7 @@ Returned value:
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_NETWORK_GET (74)
|
||||
bl - SSF_RX_PACKET_DROP_COUNT (15)
|
||||
bl - SSF_RX_PACKET_DROP_COUNT (12)
|
||||
======================================================================
|
||||
==== Function 74, Subfunction 16, Get RX missed packets counter. =====
|
||||
======================================================================
|
||||
@@ -5236,41 +5174,19 @@ Returned value:
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_NETWORK_PROTOCOL (76)
|
||||
ebx - SSF_ETHERNET_READ_MAC (0x0000)
|
||||
ebx - SSF_IP4_PACKETS_SENT (0x10000)
|
||||
ebx - SSF_IP4_PACKETS_RECEIVED (0x10001)
|
||||
ebx - SSF_IP4_READ_IP (0x10002)
|
||||
ebx - SSF_IP4_WRITE_IP (0x10003)
|
||||
ebx - SSF_IP4_READ_DNS (0x10004)
|
||||
ebx - SSF_IP4_WRITE_DNS (0x10005)
|
||||
ebx - SSF_IP4_READ_SUBNET (0x10006)
|
||||
ebx - SSF_IP4_WRITE_SUBNET (0x10007)
|
||||
ebx - SSF_IP4_READ_GATEWAY (0x10008)
|
||||
ebx - SSF_IP4_WRITE_GATEWAY (0x10009)
|
||||
ebx - SSF_ICMP_PACKETS_SENT (0x20000)
|
||||
ebx - SSF_ICMP_PACKETS_RECEIVED (0x20001)
|
||||
ebx - SSF_ICMP_ECHO_REPLY (0x20003)
|
||||
ebx - SSF_UDP_PACKETS_SENT (0x30000)
|
||||
ebx - SSF_UDP_PACKETS_RECEIVED (0x30001)
|
||||
ebx - SSF_TCP_PACKETS_SENT (0x40000)
|
||||
ebx - SSF_TCP_PACKETS_RECEIVED (0x40001)
|
||||
ebx - SSF_ARP_PACKETS_SENT (0x50000)
|
||||
ebx - SSF_ARP_PACKETS_RECEIVED (0x50001)
|
||||
ebx - SSF_ARP_GET_ENTRY_COUNT (0x50002)
|
||||
ebx - SSF_ARP_READ_ENTRY (0x50003)
|
||||
ebx - SSF_ARP_ADD_STATIC_ENTRY (0x50004)
|
||||
ebx - SSF_ARP_DEL_ENTRY (0x50005)
|
||||
ebx - SSF_ARP_SEND_ANNOUNCE (0x50006)
|
||||
ebx - SSF_ARP_CONFLICTS_COUNT (0x50007)
|
||||
======================================================================
|
||||
========== Function 77, Subfunction 0, Create futex object ===========
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 77 - function number
|
||||
* ebx = 0 - subfunction number
|
||||
* ecx = futex control value (dword)
|
||||
* ecx = pointer to futex dword
|
||||
Returned value:
|
||||
* eax = futex handle, 0 on error
|
||||
Remarks:
|
||||
* Use subfunction 1 to destroy the futex.
|
||||
The kernel destroys the futexes automatically when the process
|
||||
terminates.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
@@ -5285,8 +5201,7 @@ Parameters:
|
||||
Returned value:
|
||||
* eax = 0 - successfull, -1 on error
|
||||
Remarks:
|
||||
* The kernel destroys the futexes automatically when the process
|
||||
terminates.
|
||||
* The futex handle must have been created by subfunction 0
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
@@ -5298,12 +5213,17 @@ Parameters:
|
||||
* eax = 77 - function number
|
||||
* ebx = 2 - subfunction number
|
||||
* ecx = futex handle
|
||||
* edx = futex control value (dword)
|
||||
* esi = timeout in hundredths of a second, 0 - wait forever
|
||||
* edx = control value
|
||||
* esi = timeout in system ticks or 0 for infinity
|
||||
Returned value:
|
||||
* eax = 0 - successfull
|
||||
-1 - timeout
|
||||
-2 - futex control value doesn't match
|
||||
-1 - timeout
|
||||
-2 - futex dword does not have the same value as edx
|
||||
Remarks:
|
||||
* This functionn tests that the value at the futex dword still
|
||||
contains the expected control value, and if so, then sleeps
|
||||
waiting for a wake operation on the futex.
|
||||
* The futex handle must have been created by subfunction 0
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
@@ -5319,71 +5239,15 @@ Parameters:
|
||||
Returned value:
|
||||
* eax = number of waiters that were woken up
|
||||
|
||||
Remarks:
|
||||
* This function wakes at most edx of the waiters that are
|
||||
waiting (e.g., inside futex wait) on the futex dword
|
||||
* The futex handle must have been created by subfunction 0
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
ebx - SSF_WAKE (3)
|
||||
======================================================================
|
||||
Remarks:
|
||||
* Subfunctions 4-7 are reserved and currently return -1.
|
||||
* Subfunctions 8-9 and 12 are not implemented and return -EBADF (-9).
|
||||
======================================================================
|
||||
============ Function 77, Subfunction 10, Read from file. ============
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 77 - function number
|
||||
* ebx = 10 - subfunction number
|
||||
* ecx = file handle
|
||||
* edx = pointer to destination buffer
|
||||
* esi = number of bytes to read
|
||||
Returned value:
|
||||
* eax = number of bytes read,
|
||||
0 on EOF,
|
||||
-EBADF (-9) on error
|
||||
Remarks:
|
||||
* Only pipe descriptors are supported.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
ebx - SSF_FILE_READ (10)
|
||||
======================================================================
|
||||
=========== Function 77, Subfunction 11, Write to file. =============
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 77 - function number
|
||||
* ebx = 11 - subfunction number
|
||||
* ecx = file handle
|
||||
* edx = pointer to source buffer
|
||||
* esi = number of bytes to write
|
||||
Returned value:
|
||||
* eax = number of bytes written,
|
||||
-EBADF (-9) on error,
|
||||
-EPIPE (-32) if no readers
|
||||
Remarks:
|
||||
* Only pipe descriptors are supported.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
ebx - SSF_FILE_WRITE (11)
|
||||
======================================================================
|
||||
========== Function 77, Subfunction 13, Create pipe. ================
|
||||
======================================================================
|
||||
Parameters:
|
||||
* eax = 77 - function number
|
||||
* ebx = 13 - subfunction number
|
||||
* ecx = pointer to pipefd[2] array (two dword handles)
|
||||
* edx = flags (only O_CLOEXEC is allowed)
|
||||
Returned value:
|
||||
* eax = 0 on success,
|
||||
negative errno value on error:
|
||||
-EINVAL (-11), -EFAULT (-14), -ENFILE (-23), -EMFILE (-24)
|
||||
Remarks:
|
||||
* On success, pipefd[0] is a read handle and pipefd[1] is a
|
||||
write handle.
|
||||
|
||||
---------------------- Constants for registers: ----------------------
|
||||
eax - SF_FUTEX (77)
|
||||
ebx - SSF_PIPE_CREATE (13)
|
||||
======================================================================
|
||||
=== Function 80 - file system interface with parameter of encoding ===
|
||||
======================================================================
|
||||
Parameters:
|
||||
|
||||
@@ -70,11 +70,11 @@ SF_SYSTEM=18
|
||||
SSF_WINDOW_BEHAVIOR=25 ; window focus relation with other windows
|
||||
SSSF_GET_WB=1
|
||||
SSSF_SET_WB=2
|
||||
SF_MIDI=20 ; deprecated/undefined in current kernel
|
||||
SSF_RESET=1 ; deprecated
|
||||
SSF_OUTPUT=2 ; deprecated
|
||||
SF_MIDI=20
|
||||
SSF_RESET=1
|
||||
SSF_OUTPUT=2
|
||||
SF_SYSTEM_SET=21
|
||||
SSF_MPU_MIDI_BASE=1 ; not used (reserved)
|
||||
SSF_MPU_MIDI_BASE=1
|
||||
SSF_KEYBOARD_LAYOUT=2
|
||||
SSF_SYS_LANG=5
|
||||
SSF_ACCESS_HD_LBA=11 ; setting of low-level access to HD
|
||||
@@ -112,7 +112,7 @@ SF_BACKGROUND_GET=39
|
||||
;SSF_PIXEL_BG=2
|
||||
;SSF_MODE_BG=4
|
||||
SF_SET_EVENTS_MASK=40 ; turn on/off desired events
|
||||
SF_PORT_IN_OUT=43 ; deprecated/undefined in current kernel
|
||||
SF_PORT_IN_OUT=43 ; input/output to a port
|
||||
SF_SET_PORTS=46 ; reserve/free a group of input/output ports
|
||||
SF_DRAW_NUMBER=47 ; draw number to the window
|
||||
SF_STYLE_SETTINGS=48
|
||||
@@ -132,10 +132,6 @@ SF_STYLE_SETTINGS=48
|
||||
SF_APM=49
|
||||
SF_SET_WINDOW_SHAPE=50
|
||||
SF_CREATE_THREAD=51
|
||||
SSF_CREATE_THREAD=1
|
||||
SSF_GET_CURR_THREAD_SLOT=2
|
||||
SSF_GET_THREAD_PRIORITY=3
|
||||
SSF_SET_THREAD_PRIORITY=4
|
||||
SF_CLIPBOARD=54
|
||||
SSF_GET_SLOT_COUNT=0 ; get the number of slots in the clipboard
|
||||
SSF_READ_CB=1
|
||||
@@ -188,7 +184,7 @@ SF_SYS_MISC=68
|
||||
SSF_HEAP_INIT=11
|
||||
SSF_MEM_ALLOC=12
|
||||
SSF_MEM_FREE=13
|
||||
SSF_WAIT_SIGNAL=14 ; wait for a signal from other process
|
||||
SSF_WAIT_SIGNAL=14 ; wait for signal from another program/driver
|
||||
SSF_LOAD_DRIVER=16
|
||||
SSF_CONTROL_DRIVER=17
|
||||
SSF_LOAD_DLL=19
|
||||
@@ -200,9 +196,6 @@ SF_SYS_MISC=68
|
||||
SSF_SET_EXCEPTION_STATE=25
|
||||
SSF_MEM_FREE_EXT=26
|
||||
SSF_LOAD_FILE=27
|
||||
SSF_MEM_ALLOC_RING=29
|
||||
SSF_UNLOAD_DRIVER=30
|
||||
SSF_GET_DRIVER_DATA=31
|
||||
SF_DEBUG=69
|
||||
SSF_SET_MESSAGE_AREA=0
|
||||
SSF_GET_REGISTERS=1
|
||||
@@ -228,7 +221,7 @@ SF_FILE=70
|
||||
SF_SET_CAPTION=71
|
||||
SF_SEND_MESSAGE=72
|
||||
SF_BLITTER=73
|
||||
SF_NETWORK_GET=74
|
||||
SF_NETWORK_DEVICE=74
|
||||
SSF_DEVICE_COUNT=255 ; get number of active network devices
|
||||
SSF_DEVICE_TYPE=0
|
||||
SSF_DEVICE_NAME=1
|
||||
@@ -257,7 +250,7 @@ SF_NETWORK_SOCKET=75
|
||||
SSF_RECEIVE=7
|
||||
SSF_SET_OPTIONS=8
|
||||
SSF_GET_OPTIONS=9
|
||||
SSF_GET_PAIR=10
|
||||
SSF_SOCKET_PAIR=10
|
||||
SF_NETWORK_PROTOCOL=76
|
||||
SSF_ETHERNET_READ_MAC=0
|
||||
SSF_IP4_PACKETS_SENT=10000h
|
||||
@@ -290,9 +283,6 @@ SF_FUTEX=77
|
||||
SSF_DESTROY=1
|
||||
SSF_WAIT=2
|
||||
SSF_WAKE=3
|
||||
SSF_FILE_READ=10
|
||||
SSF_FILE_WRITE=11
|
||||
SSF_PIPE_CREATE=13
|
||||
|
||||
; File system errors:
|
||||
FSERR_SUCCESS=0
|
||||
|
||||
@@ -172,7 +172,7 @@ else
|
||||
end if
|
||||
}
|
||||
|
||||
include '../../KOSfuncs.inc'
|
||||
include 'kosfuncs.inc'
|
||||
include '../../macros.inc'
|
||||
|
||||
include 'font.inc'
|
||||
|
||||
298
programs/develop/koldbg/kosfuncs.inc
Normal file
298
programs/develop/koldbg/kosfuncs.inc
Normal file
@@ -0,0 +1,298 @@
|
||||
|
||||
; KolibriOS system functions:
|
||||
SF_TERMINATE_PROCESS=-1
|
||||
SF_CREATE_WINDOW=0 ; define and draw the window
|
||||
SF_PUT_PIXEL=1 ; draw pixel to the window
|
||||
SF_GET_KEY=2 ; get code of the pressed key
|
||||
SF_GET_SYS_TIME=3
|
||||
SF_DRAW_TEXT=4
|
||||
SF_SLEEP=5 ; pause process
|
||||
SF_PUT_IMAGE=7 ; draw image to the window
|
||||
SF_DEFINE_BUTTON=8 ; define/delete the button
|
||||
SF_THREAD_INFO=9 ; information on execution thread
|
||||
SF_WAIT_EVENT=10 ; wait for event
|
||||
SF_CHECK_EVENT=11 ; check for event and return
|
||||
SF_REDRAW=12
|
||||
SSF_BEGIN_DRAW=1
|
||||
SSF_END_DRAW=2
|
||||
SF_DRAW_RECT=13 ; draw rectangle to the window
|
||||
SF_GET_SCREEN_SIZE=14 ; get screen resolution
|
||||
SF_BACKGROUND_SET=15 ; work with desktop background graphics
|
||||
SSF_SIZE_BG=1 ; set a size of the background image
|
||||
SSF_PIXEL_BG=2 ; put pixel on the background image
|
||||
SSF_REDRAW_BG=3 ; redraw background
|
||||
SSF_MODE_BG=4 ; set drawing mode for the background
|
||||
SSF_IMAGE_BG=5 ; put block of pixels on the background image
|
||||
SSF_MAP_BG=6 ; map background image to the address space of the process
|
||||
SSF_UNMAP_BG=7 ; close mapped background data
|
||||
SSF_LAST_DRAW=8 ; get coordinates of the last draw to the background
|
||||
SSF_REDRAW_RECT=9 ; redraws a rectangular part of the background
|
||||
SF_RD_TO_FLOPPY=16 ; save ramdisk on the floppy
|
||||
SF_GET_BUTTON=17 ; get ID of the pressed button
|
||||
SF_SYSTEM=18
|
||||
SSF_UNFOCUS_WINDOW=1 ; take focus from the window of the given thread
|
||||
SSF_TERMINATE_THREAD=2 ; terminate process/thread by the slot number
|
||||
SSF_FOCUS_WINDOW=3 ; give focus to the window of the given thread
|
||||
SSF_GET_IDLE_COUNT=4 ; get counter of idle cycles per second
|
||||
SSF_GET_CPU_FREQUENCY=5 ; get CPU clock rate
|
||||
SSF_RD_TO_HDD=6 ; save ramdisk to the file on hard disk
|
||||
SSF_GET_ACTIVE_WINDOW=7 ; get slot number of the active window
|
||||
SSF_SPEAKER=8
|
||||
SSSF_GET_STATE=1
|
||||
SSSF_TOGGLE=2
|
||||
SSF_SHUTDOWN=9 ; system shutdown/reboot
|
||||
SSF_MINIMIZE_WINDOW=10 ; minimize active window
|
||||
SSF_INFO_DISC_SYS=11 ; get disk subsystem information
|
||||
SSF_KERNEL_VERSION=13 ; get kernel version
|
||||
SSF_WAIT_RETRACE=14 ; wait for screen retrace
|
||||
SSF_CURSOR_CENTER=15 ; center mouse cursor on the screen
|
||||
SSF_GET_FREE_RAM=16 ; get size of free RAM
|
||||
SSF_GET_TOTAL_RAM=17 ; get total amount of RAM
|
||||
SSF_TERMINATE_THREAD_ID=18 ; Terminate process/thread by the ID
|
||||
SSF_MOUSE_SETTINGS=19
|
||||
SSSF_GET_SPEED=0
|
||||
SSSF_SET_SPEED=1
|
||||
SSSF_GET_SPEEDUP=2
|
||||
SSSF_SET_SPEEDUP=3 ; set mouse acceleration
|
||||
SSSF_SET_POS=4 ; set mouse pointer position
|
||||
SSSF_SET_BUTTON=5 ; simulate state of mouse buttons
|
||||
SSSF_GET_DOUBLE_CLICK_DELAY=6
|
||||
SSSF_SET_DOUBLE_CLICK_DELAY=7
|
||||
SSF_GET_RAM_INFO=20 ; get information on RAM
|
||||
SSF_GET_THREAD_SLOT=21 ; get slot number of process/thread by the ID
|
||||
SSF_FOREIGN_WINDOW=22 ; operations with window of another thread by slot/ID
|
||||
SSSF_MINIMIZE=0
|
||||
SSSF_MINIMIZE_ID=1
|
||||
SSSF_RESTORE=2
|
||||
SSSF_RESTORE_ID=3
|
||||
SSF_MINIMIZE_ALL=23
|
||||
SSF_SET_SCREEN_LIMITS=24
|
||||
SSF_WINDOW_BEHAVIOR=25 ; window focus relation with other windows
|
||||
SSSF_GET_WB=1
|
||||
SSSF_SET_WB=2
|
||||
SF_MIDI=20
|
||||
SSF_RESET=1
|
||||
SSF_OUTPUT=2
|
||||
SF_SYSTEM_SET=21
|
||||
SSF_MPU_MIDI_BASE=1
|
||||
SSF_KEYBOARD_LAYOUT=2
|
||||
SSF_SYS_LANG=5
|
||||
SSF_ACCESS_HD_LBA=11 ; setting of low-level access to HD
|
||||
SSF_ACCESS_PCI=12 ; setting of low-level access to PCI
|
||||
SF_SET_TIME_DATE=22
|
||||
SF_WAIT_EVENT_TIMEOUT=23; wait for event with timeout
|
||||
SF_CD=24
|
||||
SSF_EJECT_TRAY=4
|
||||
SSF_INSERT_TRAY=5
|
||||
SF_SCREEN_PUT_IMAGE=25 ; put image on the background layer
|
||||
SF_SYSTEM_GET=26
|
||||
; Same as SF_SYSTEM_SET, plus:
|
||||
SSF_TIME_COUNT=9
|
||||
SSF_TIME_COUNT_PRO=10 ; get value of the high precision time counter
|
||||
SF_GET_SYS_DATE=29
|
||||
SF_CURRENT_FOLDER=30
|
||||
SSF_SET_CF=1 ; set current folder for the thread
|
||||
SSF_GET_CF=2
|
||||
SSF_ADD_SYS_FOLDER=3 ; install the add.system directory for the kernel
|
||||
SF_GET_PIXEL_OWNER=34 ; get slot number of the screen pixel owner
|
||||
SF_GET_PIXEL=35 ; read the screen pixel color
|
||||
SF_GET_IMAGE=36 ; read the screen area
|
||||
SF_MOUSE_GET=37
|
||||
SSF_SCREEN_POSITION=0
|
||||
SSF_WINDOW_POSITION=1
|
||||
SSF_BUTTON=2 ; states of the mouse buttons
|
||||
SSF_BUTTON_EXT=3 ; states and events of the mouse buttons
|
||||
SSF_LOAD_CURSOR=4
|
||||
SSF_SET_CURSOR=5
|
||||
SSF_DEL_CURSOR=6
|
||||
SSF_SCROLL_DATA=7
|
||||
SF_DRAW_LINE=38
|
||||
SF_BACKGROUND_GET=39
|
||||
;SSF_SIZE_BG=1
|
||||
;SSF_PIXEL_BG=2
|
||||
;SSF_MODE_BG=4
|
||||
SF_SET_EVENTS_MASK=40 ; turn on/off desired events
|
||||
SF_PORT_IN_OUT=43 ; input/output to a port
|
||||
SF_SET_PORTS=46 ; reserve/free a group of input/output ports
|
||||
SF_DRAW_NUMBER=47 ; draw number to the window
|
||||
SF_STYLE_SETTINGS=48
|
||||
SSF_APPLY=0 ; apply screen settings
|
||||
SSF_SET_BUTTON_STYLE=1
|
||||
SSF_SET_COLORS=2
|
||||
SSF_GET_COLORS=3 ; get standard window colors
|
||||
SSF_GET_SKIN_HEIGHT=4
|
||||
SSF_GET_SCREEN_AREA=5 ; get screen working area
|
||||
SSF_SET_SCREEN_AREA=6
|
||||
SSF_GET_SKIN_MARGINS=7
|
||||
SSF_SET_SKIN=8
|
||||
SSF_GET_FONT_SMOOTH=9
|
||||
SSF_SET_FONT_SMOOTH=10
|
||||
SSF_GET_FONT_SIZE=11
|
||||
SSF_SET_FONT_SIZE=12
|
||||
SF_APM=49
|
||||
SF_SET_WINDOW_SHAPE=50
|
||||
SF_CREATE_THREAD=51
|
||||
SF_CLIPBOARD=54
|
||||
SSF_GET_SLOT_COUNT=0 ; get the number of slots in the clipboard
|
||||
SSF_READ_CB=1
|
||||
SSF_WRITE_CB=2
|
||||
SSF_DEL_SLOT=3 ; delete the last slot in the clipboard
|
||||
SSF_UNLOCK_BUFFER=4 ; emergency buffer unlock
|
||||
SF_SPEAKER_PLAY=55
|
||||
SF_PCI_BIOS=57
|
||||
SF_IPC=60 ; Inter Process Communication
|
||||
SSF_SET_AREA=1 ; set area for IPC receiving
|
||||
SSF_SEND_MESSAGE=2
|
||||
SF_GET_GRAPHICAL_PARAMS=61
|
||||
SSF_SCREEN_SIZE=1
|
||||
SSF_BITS_PER_PIXEL=2
|
||||
SSF_BYTES_PER_LINE=3
|
||||
SF_PCI=62
|
||||
SSF_GET_VERSION=0 ; get version of PCI-interface
|
||||
SSF_GET_LAST_BUS=1 ; get number of the last PCI-bus
|
||||
SSF_GET_ADRR_MODE=2 ; get addressing mode of the PCI configuration space
|
||||
SSF_READ_BYTE=4
|
||||
SSF_READ_WORD=5
|
||||
SSF_READ_DWORD=6
|
||||
SSF_WRITE_BYTE=8
|
||||
SSF_WRITE_WORD=9
|
||||
SSF_WRITE_DWORD=10
|
||||
SF_BOARD=63
|
||||
SSF_DEBUG_WRITE=1
|
||||
SSF_DEBUG_READ=2
|
||||
SF_MEMORY_RESIZE=64 ; resize total application memory
|
||||
SF_PUT_IMAGE_EXT=65 ; draw image with palette to the window
|
||||
SF_KEYBOARD=66
|
||||
SSF_SET_INPUT_MODE=1
|
||||
SSF_GET_INPUT_MODE=2
|
||||
SSF_GET_CONTROL_KEYS=3; get status of control keys
|
||||
SSF_SET_SYS_HOTKEY=4
|
||||
SSF_DEL_SYS_HOTKEY=5
|
||||
SSF_LOCK_INPUT=6 ; block normal input
|
||||
SSF_UNLOCK_INPUT=7 ; restore normal input
|
||||
SF_CHANGE_WINDOW=67 ; change position/sizes of the window
|
||||
SF_SYS_MISC=68
|
||||
SSF_GET_TASK_SWITCH_COUNT=0
|
||||
SSF_SWITCH_TASK=1
|
||||
SSF_PERFORMANCE=2
|
||||
SSSF_ALLOW_RDPMC=0
|
||||
SSSF_CACHE_STATUS=1
|
||||
SSSF_CACHE_ON=2
|
||||
SSSF_CACHE_OFF=3
|
||||
SSF_READ_MSR=3
|
||||
SSF_WRITE_MSR=4
|
||||
SSF_HEAP_INIT=11
|
||||
SSF_MEM_ALLOC=12
|
||||
SSF_MEM_FREE=13
|
||||
SSF_WAIT_SIGNAL=14 ; wait for signal from another program/driver
|
||||
SSF_LOAD_DRIVER=16
|
||||
SSF_CONTROL_DRIVER=17
|
||||
SSF_LOAD_DLL=19
|
||||
SSF_MEM_REALLOC=20
|
||||
SSF_LOAD_DRIVER_PE=21
|
||||
SSF_MEM_OPEN=22 ; open named memory area
|
||||
SSF_MEM_CLOSE=23
|
||||
SSF_SET_EXCEPTION_HANDLER=24
|
||||
SSF_SET_EXCEPTION_STATE=25
|
||||
SSF_MEM_FREE_EXT=26
|
||||
SSF_LOAD_FILE=27
|
||||
SF_DEBUG=69
|
||||
SSF_SET_MESSAGE_AREA=0
|
||||
SSF_GET_REGISTERS=1
|
||||
SSF_SET_REGISTERS=2
|
||||
SSF_DETACH=3
|
||||
SSF_SUSPEND=4
|
||||
SSF_RESUME=5
|
||||
SSF_READ_MEMORY=6
|
||||
SSF_WRITE_MEMORY=7
|
||||
SSF_TERMINATE=8
|
||||
SSF_DEFINE_BREAKPOINT=9
|
||||
SF_FILE=70
|
||||
SSF_READ_FILE=0
|
||||
SSF_READ_FOLDER=1
|
||||
SSF_CREATE_FILE=2
|
||||
SSF_WRITE_FILE=3
|
||||
SSF_SET_END=4
|
||||
SSF_GET_INFO=5
|
||||
SSF_SET_INFO=6
|
||||
SSF_START_APP=7
|
||||
SSF_DELETE=8
|
||||
SSF_CREATE_FOLDER=9
|
||||
SF_SET_CAPTION=71
|
||||
SF_SEND_MESSAGE=72
|
||||
SF_BLITTER=73
|
||||
SF_NETWORK_DEVICE=74
|
||||
SSF_DEVICE_COUNT=255 ; get number of active network devices
|
||||
SSF_DEVICE_TYPE=0
|
||||
SSF_DEVICE_NAME=1
|
||||
SSF_RESET_DEVICE=2
|
||||
SSF_STOP_DEVICE=3
|
||||
SSF_DEVICE_POINTER=4
|
||||
SSF_TX_PACKET_COUNT=6
|
||||
SSF_RX_PACKET_COUNT=7
|
||||
SSF_TX_BYTE_COUNT=8
|
||||
SSF_RX_BYTE_COUNT=9
|
||||
SSF_LINK_STATUS=10
|
||||
SSF_TX_PACKET_ERROR_COUNT=11
|
||||
SSF_TX_PACKET_DROP_COUNT=12
|
||||
SSF_TX_PACKET_MISS_COUNT=13
|
||||
SSF_RX_PACKET_ERROR_COUNT=14
|
||||
SSF_RX_PACKET_DROP_COUNT=15
|
||||
SSF_RX_PACKET_MISS_COUNT=16
|
||||
SF_NETWORK_SOCKET=75
|
||||
SSF_OPEN=0
|
||||
SSF_CLOSE=1
|
||||
SSF_BIND=2
|
||||
SSF_LISTEN=3
|
||||
SSF_CONNECT=4
|
||||
SSF_ACCEPT=5
|
||||
SSF_SEND=6
|
||||
SSF_RECEIVE=7
|
||||
SSF_SET_OPTIONS=8
|
||||
SSF_GET_OPTIONS=9
|
||||
SSF_SOCKET_PAIR=10
|
||||
SF_NETWORK_PROTOCOL=76
|
||||
SSF_ETHERNET_READ_MAC=0
|
||||
SSF_IP4_PACKETS_SENT=10000h
|
||||
SSF_IP4_PACKETS_RECEIVED=10001h
|
||||
SSF_IP4_READ_IP=10002h
|
||||
SSF_IP4_WRITE_IP=10003h
|
||||
SSF_IP4_READ_DNS=10004h
|
||||
SSF_IP4_WRITE_DNS=10005h
|
||||
SSF_IP4_READ_SUBNET=10006h
|
||||
SSF_IP4_WRITE_SUBNET=10007h
|
||||
SSF_IP4_READ_GATEWAY=10008h
|
||||
SSF_IP4_WRITE_GATEWAY=10009h
|
||||
SSF_ICMP_PACKETS_SENT=20000h
|
||||
SSF_ICMP_PACKETS_RECEIVED=20001h
|
||||
SSF_ICMP_ECHO_REPLY=20003h
|
||||
SSF_UDP_PACKETS_SENT=30000h
|
||||
SSF_UDP_PACKETS_RECEIVED=30001h
|
||||
SSF_TCP_PACKETS_SENT=40000h
|
||||
SSF_TCP_PACKETS_RECEIVED=40001h
|
||||
SSF_ARP_PACKETS_SENT=50000h
|
||||
SSF_ARP_PACKETS_RECEIVED=50001h
|
||||
SSF_ARP_GET_ENTRY_COUNT=50002h
|
||||
SSF_ARP_READ_ENTRY=50003h
|
||||
SSF_ARP_ADD_STATIC_ENTRY=50004h
|
||||
SSF_ARP_DEL_ENTRY=50005h
|
||||
SSF_ARP_SEND_ANNOUNCE=50006h
|
||||
SSF_ARP_CONFLICTS_COUNT=50007h
|
||||
SF_FUTEX=77
|
||||
SSF_CREATE=0
|
||||
SSF_DESTROY=1
|
||||
SSF_WAIT=2
|
||||
SSF_WAKE=3
|
||||
|
||||
; File system errors:
|
||||
FSERR_SUCCESS=0
|
||||
FSERR_UNSUPPORTED=2
|
||||
FSERR_UNKNOWN=3
|
||||
FSERR_FILE_NOT_FOUND=5
|
||||
FSERR_END_OF_FILE=6
|
||||
FSERR_INVALID_BUFFER=7
|
||||
FSERR_DISK_FULL=8
|
||||
FSERR_FAIL=9
|
||||
FSERR_ACCESS_DENIED=10
|
||||
FSERR_DEVICE_FAIL=11
|
||||
FSERR_OUT_OF_MEMORY=12
|
||||
4
programs/develop/ktcc/trunk/libc.obj/.gitignore
vendored
Normal file
4
programs/develop/ktcc/trunk/libc.obj/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.tup
|
||||
*.o
|
||||
*.obj
|
||||
*.kex
|
||||
@@ -8,6 +8,9 @@
|
||||
#define NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
#define EXIT_SUCCESS 0 // Successful execution of a program
|
||||
#define EXIT_FAILURE 1 // Unsuccessful execution of a program
|
||||
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ DLLAPI char* strrchr(const char* s, int c);
|
||||
DLLAPI size_t strspn(const char* s1, const char* s2);
|
||||
DLLAPI char* strstr(const char* s1, const char* s2);
|
||||
DLLAPI char* strtok(char* s1, const char* s2);
|
||||
DLLAPI char* strtok_r(char* s1, const char* s2, char** saveptr);
|
||||
DLLAPI char* strerror(int errnum);
|
||||
DLLAPI size_t strlen(const char* s);
|
||||
DLLAPI char* strrev(char* str);
|
||||
|
||||
@@ -120,7 +120,7 @@ typedef struct {
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t cpu_usage; // CPU usage (cycles per secondes)
|
||||
uint32_t cpu_usage; // CPU usage (cycles per secondgoes)
|
||||
uint16_t pos_in_window_stack; // position of the thread window in the window stack
|
||||
uint16_t slot_num_window_stack; // slot number in window stack
|
||||
uint16_t __reserved1; // reserved
|
||||
@@ -214,30 +214,6 @@ typedef struct {
|
||||
uint32_t pitch;
|
||||
} ksys_blitter_params_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t a, b, c, d;
|
||||
uint8_t debug_label;
|
||||
uint8_t ABI_low;
|
||||
uint8_t ABI_high;
|
||||
uint32_t commit_id;
|
||||
uint16_t reserved;
|
||||
uint16_t commit_count;
|
||||
} ksys_kernel_version_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total_ram_pages;
|
||||
uint32_t free_ram_pages;
|
||||
uint32_t page_faults;
|
||||
uint32_t kernel_heap_size;
|
||||
uint32_t kernel_heap_free;
|
||||
uint32_t kernel_heap_total_blocks;
|
||||
uint32_t kernel_heap_free_blocks;
|
||||
uint32_t kernel_heap_largest_free_block;
|
||||
uint32_t kernel_heap_largest_alloc_block;
|
||||
|
||||
} ksys_memory_info_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef rgb_t ksys_bitmap_t;
|
||||
@@ -382,10 +358,10 @@ enum KSYS_SCANCODES {
|
||||
KSYS_SCANCODE_EXT_INSERT = 82,
|
||||
KSYS_SCANCODE_NUMPAD_COMMA = 83,
|
||||
KSYS_SCANCODE_EXT_DELETE = 83,
|
||||
// 84-86 doesn't exist
|
||||
//84-86 doesn't exist
|
||||
KSYS_SCANCODE_F11 = 87,
|
||||
KSYS_SCANCODE_F12 = 88,
|
||||
// 89,90 doesn't exist
|
||||
//89,90 doesn't exist
|
||||
KSYS_SCANCODE_EXT_LWIN = 91,
|
||||
KSYS_SCANCODE_EXT_RWIN = 92,
|
||||
KSYS_SCANCODE_EXT_MENU = 93,
|
||||
@@ -783,40 +759,6 @@ KOSAPI void _ksys_shutdown(uint32_t shd_param)
|
||||
asm_inline("int $0x40" ::"a"(18), "b"(9), "c"(shd_param));
|
||||
}
|
||||
|
||||
/*====== Function 18, subfunction 10 - minimize current window. ========*/
|
||||
|
||||
KOSAPI void _ksys_minimize_current_windows()
|
||||
{
|
||||
asm_inline(
|
||||
"int $0x40" ::"a"(18), "b"(10));
|
||||
}
|
||||
|
||||
/*========== Function 18, subfunction 13 - get kernel version. =========*/
|
||||
|
||||
KOSAPI int _ksys_get_kernel_version(ksys_kernel_version_t* info)
|
||||
{
|
||||
int err;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(18), "b"(13), "c"(info)
|
||||
: "memory");
|
||||
return err;
|
||||
}
|
||||
|
||||
/*========= Function 18, subfunction 15 - move mouse to center. ========*/
|
||||
|
||||
KOSAPI int _ksys_center_mouse()
|
||||
{
|
||||
int a;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(a)
|
||||
: "a"(18), "b"(15));
|
||||
return a;
|
||||
}
|
||||
|
||||
/*========= Function 18, subfunction 16 - get size of free RAM. ========*/
|
||||
|
||||
KOSAPI size_t _ksys_get_ram_size(void)
|
||||
@@ -875,19 +817,6 @@ KOSAPI uint32_t _ksys_set_mouse_settings(ksys_mouse_settings_t settings, uint32_
|
||||
|
||||
#define _ksys_set_mouse_pos(X, Y) _ksys_set_mouse_settings(KSYS_MOUSE_SET_POS, X * 65536 + Y)
|
||||
|
||||
/*===================== Function 18, subfunction 20 ====================*/
|
||||
|
||||
KOSAPI int _ksys_get_memory_info(ksys_memory_info_t* info)
|
||||
{
|
||||
int total;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(total)
|
||||
: "a"(18), "b"(20), "c"(info)
|
||||
: "memory");
|
||||
return total;
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 21 ====================*/
|
||||
/*=====Get the slot number of the process / thread by identifier.. =====*/
|
||||
|
||||
@@ -901,185 +830,6 @@ KOSAPI int _ksys_get_thread_slot(int PID)
|
||||
return val;
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 22 ====================*/
|
||||
|
||||
typedef enum KSYS_WIN_REMOTE_CONTROL {
|
||||
WIN_MINIMIZE_BY_SLOT = 0,
|
||||
WIN_MINIMIZE_BY_PID = 1,
|
||||
WIN_RESTORE_BY_SLOT = 2,
|
||||
WIN_RESTORE_BY_PID = 3
|
||||
} ksys_win_remote_control_t;
|
||||
|
||||
KOSAPI int _ksys_window_remote_control(ksys_win_remote_control_t type, uint32_t param)
|
||||
{
|
||||
int result;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(result)
|
||||
: "a"(18), "b"(22), "c"(type), "d"(param));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 23 ====================*/
|
||||
|
||||
KOSAPI int _ksys_minimize_all_windows()
|
||||
{
|
||||
int count;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(count)
|
||||
: "a"(18), "b"(23));
|
||||
return count;
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 24 ====================*/
|
||||
|
||||
KOSAPI void _ksys_set_draw_limits(unsigned int x, unsigned int y)
|
||||
{
|
||||
asm_inline(
|
||||
"int $0x40" ::"a"(18), "b"(24), "c"(x), "d"(y));
|
||||
}
|
||||
|
||||
/*===================== Function 18, subfunction 25 ====================*/
|
||||
|
||||
typedef enum KSYS_ZPOS {
|
||||
KSYS_ZPOS_DESKTOP = -2,
|
||||
KSYS_ZPOS_ALWAYS_BACK = -1,
|
||||
KSYS_ZPOS_NORMAL = 0,
|
||||
KSYS_ZPOS_ALWAYS_TOP = 1
|
||||
} ksys_zpos_t;
|
||||
|
||||
/*=========== Function 18, subfunction 25, subsubfunction 1 ============*/
|
||||
|
||||
KOSAPI ksys_zpos_t _ksys_get_window_zposition(int32_t pid)
|
||||
{
|
||||
ksys_zpos_t result_eax;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(result_eax)
|
||||
: "a"(18), "b"(25), "c"(1), "d"(pid));
|
||||
|
||||
return result_eax;
|
||||
}
|
||||
|
||||
/*=========== Function 18, subfunction 25, subsubfunction 2 ============*/
|
||||
|
||||
KOSAPI int _ksys_set_window_zposition(int32_t pid, ksys_zpos_t position)
|
||||
{
|
||||
int err;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(18), "b"(25), "c"(2), "d"(pid), "S"(position));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*==================== Function 21, subfunction 2 =====================*/
|
||||
|
||||
typedef enum KSYS_KEYBOARD_LAYOUT {
|
||||
KSYS_KEYBOARD_LAYOUT_NORMAL = 1,
|
||||
KSYS_KEYBOARD_LAYOUT_SHIFT = 2,
|
||||
KSYS_KEYBOARD_LAYOUT_ALT = 3
|
||||
} ksys_keyboard_layout_t;
|
||||
|
||||
KOSAPI int _ksys_set_keyboard_layout(ksys_keyboard_layout_t mode, char* table)
|
||||
{
|
||||
int err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(2), "c"(mode), "d"(table));
|
||||
return err;
|
||||
}
|
||||
|
||||
typedef enum KSYS_LANG {
|
||||
KSYS_LANG_ENG = 1,
|
||||
KSYS_LANG_FI = 2,
|
||||
KSYS_LANG_GER = 3,
|
||||
KSYS_LANG_RU = 4
|
||||
} ksys_lang_t;
|
||||
|
||||
KOSAPI int _ksys_set_keyboard_lang(ksys_lang_t lang)
|
||||
{
|
||||
int err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(2), "c"(9), "d"(lang));
|
||||
return err;
|
||||
}
|
||||
|
||||
/*==================== Function 21, subfunction 5 =====================*/
|
||||
|
||||
KOSAPI int _ksys_set_lang(ksys_lang_t lang)
|
||||
{
|
||||
int err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(5), "c"(lang));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*==================== Function 21, subfunction 11 =====================*/
|
||||
|
||||
KOSAPI int _ksys_allow_HD(int param)
|
||||
{
|
||||
int err;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(11), "c"(param));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*==================== Function 21, subfunction 12 =====================*/
|
||||
|
||||
KOSAPI int _ksys_allow_PCI(int param)
|
||||
{
|
||||
int err;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(21), "b"(12), "c"(param));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
typedef enum KSYS_SET_TIME_ERR {
|
||||
KSYS_SET_TIME_OK = 0,
|
||||
KSYS_SET_TIME_WRONG_PARAM = 1,
|
||||
KSYS_SET_TIME_CMOS = 2
|
||||
} ksys_set_time_err;
|
||||
|
||||
/*============================ Function 22 ============================*/
|
||||
|
||||
KOSAPI ksys_set_time_err _ksys_set_time(ksys_time_t time)
|
||||
{
|
||||
ksys_set_time_err err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(22), "b"(0), "c"(time));
|
||||
}
|
||||
|
||||
KOSAPI ksys_set_time_err _ksys_set_date(ksys_date_t date)
|
||||
{
|
||||
ksys_set_time_err err;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(err)
|
||||
: "a"(22), "b"(1), "c"(date));
|
||||
}
|
||||
|
||||
/*============= Function 23 - wait for event with timeout. =============*/
|
||||
|
||||
KOSAPI uint32_t _ksys_wait_event_timeout(uint32_t timeout)
|
||||
@@ -1092,37 +842,19 @@ KOSAPI uint32_t _ksys_wait_event_timeout(uint32_t timeout)
|
||||
return val;
|
||||
}
|
||||
|
||||
/*========= Function 26, subfunction 2 - get keyboard layout. ==========*/
|
||||
/*=== Function 26, subfunction 2 - get keynoard layout. ==*/
|
||||
|
||||
KOSAPI uint32_t _ksys_keyboard_layout(ksys_keyboard_layout_t layout, unsigned char* buf)
|
||||
typedef enum KSYS_KEYBOARD_LAYOUT {
|
||||
KSYS_KEYBOARD_LAYOUT_NORMAL = 1,
|
||||
KSYS_KEYBOARD_LAYOUT_SHIFT = 2,
|
||||
KSYS_KEYBOARD_LAYOUT_ALT = 3
|
||||
} ksys_keyboard_layout_t;
|
||||
|
||||
KOSAPI uint32_t _ksys_keyboard_layout(ksys_keyboard_layout_t layout, unsigned char *buf)
|
||||
{
|
||||
asm_inline("int $0x40" ::"a"(26), "b"(2), "c"(layout), "d"(buf) : "memory");
|
||||
}
|
||||
|
||||
KOSAPI ksys_lang_t _ksys_get_keyboard_lang()
|
||||
{
|
||||
ksys_lang_t lang;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(lang)
|
||||
: "a"(26), "b"(2), "c"(9));
|
||||
return lang;
|
||||
}
|
||||
|
||||
/*======= Function 26, subfunction 5 - get the system language. ========*/
|
||||
|
||||
KOSAPI ksys_lang_t _ksys_get_lang()
|
||||
{
|
||||
ksys_lang_t lang;
|
||||
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(lang)
|
||||
: "a"(26), "b"(5));
|
||||
|
||||
return lang;
|
||||
}
|
||||
|
||||
/*=== Function 26, subfunction 9 - get the value of the time counter. ==*/
|
||||
|
||||
KOSAPI uint32_t _ksys_get_tick_count(void)
|
||||
@@ -1148,30 +880,6 @@ KOSAPI uint64_t _ksys_get_ns_count(void)
|
||||
return val;
|
||||
}
|
||||
|
||||
/*===================== Function 26, subfunction 11 ====================*/
|
||||
|
||||
KOSAPI int _ksys_get_HD()
|
||||
{
|
||||
int val;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(val)
|
||||
: "a"(26), "b"(11));
|
||||
return val;
|
||||
}
|
||||
|
||||
/*===================== Function 26, subfunction 12 ====================*/
|
||||
|
||||
KOSAPI int _ksys_get_PCI()
|
||||
{
|
||||
int val;
|
||||
asm_inline(
|
||||
"int $0x40"
|
||||
: "=a"(val)
|
||||
: "a"(26), "b"(12));
|
||||
return val;
|
||||
}
|
||||
|
||||
/*=================== Function 29 - get system date. ===================*/
|
||||
|
||||
KOSAPI ksys_date_t _ksys_get_date(void)
|
||||
@@ -1502,7 +1210,7 @@ KOSAPI void _ksys_debug_puts(const char* s)
|
||||
KOSAPI void ksys_draw_bitmap_palette(void* bitmap, int x, int y, int w, int h, int bpp, void* palette, int offset)
|
||||
{
|
||||
asm_inline(
|
||||
"pushl %%ebp\n\t" // save EBP register
|
||||
"pushl %%ebp,\n\t" // save EBP register
|
||||
"movl 0x24(%%ebp), %%ebp\n\t" // 0x24 - "offset" param
|
||||
"int $0x40\n\t"
|
||||
"popl %%ebp" // restore EBP register
|
||||
@@ -1935,7 +1643,7 @@ KOSAPI void _ksys_set_window_title(const char* title)
|
||||
|
||||
/*============= Function 73 - blitter =============*/
|
||||
|
||||
KOSAPI void _ksys_blitter(uint32_t flags, ksys_blitter_params_t* params)
|
||||
KOSAPI void _ksys_blitter(uint32_t flags, ksys_blitter_params_t *params)
|
||||
{
|
||||
int res;
|
||||
asm_inline(
|
||||
|
||||
@@ -27,7 +27,8 @@ BIN = \
|
||||
libc_test.kex \
|
||||
pipe.kex \
|
||||
defgen.kex \
|
||||
futex.kex
|
||||
futex.kex \
|
||||
malloc_test.kex
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
|
||||
@@ -23,5 +23,6 @@ cp clayer/logo.png /tmp0/1/tcc_samples/logo.png
|
||||
../tcc defgen.c -o /tmp0/1/tcc_samples/defgen
|
||||
../tcc pipe.c -o /tmp0/1/tcc_samples/pipe
|
||||
../tcc futex.c -o /tmp0/1/tcc_samples/futex
|
||||
../tcc malloc_test.c -o /tmp0/1/tcc_samples/malloc_test
|
||||
"/sys/File managers/Eolite" /tmp0/1/tcc_samples
|
||||
exit
|
||||
|
||||
292
programs/develop/ktcc/trunk/libc.obj/samples/malloc_test.c
Normal file
292
programs/develop/ktcc/trunk/libc.obj/samples/malloc_test.c
Normal file
@@ -0,0 +1,292 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "../source/stdlib/_mem.h"
|
||||
|
||||
#define RUN_TEST(func) \
|
||||
printf("---\tRUN TEST: %s\t---\n", #func); \
|
||||
if (func()) { \
|
||||
printf("[SUCCESS]\tTest %s is ok.\n\n", #func); \
|
||||
} else { \
|
||||
fprintf(stderr, "[FAIL]\tTest %s failed.\n\n", #func); \
|
||||
exit(EXIT_FAILURE); \
|
||||
}
|
||||
|
||||
// c between a and b
|
||||
#define IN_RANGE(a, b, c, len) ((a > c && c > b) || ((a > c + len && c + len > b)))
|
||||
|
||||
bool test_malloc_basic_allocation()
|
||||
{
|
||||
void* ptr = malloc(sizeof(int));
|
||||
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
bool test_malloc_zero_bytes()
|
||||
{
|
||||
return malloc(0) == NULL;
|
||||
}
|
||||
|
||||
bool test_malloc_multiple_allocations()
|
||||
{
|
||||
void* ptr[512];
|
||||
|
||||
for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) {
|
||||
ptr[i] = malloc(i);
|
||||
if (ptr[i] == NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) {
|
||||
for (int j = 1; j < sizeof(ptr) / sizeof(*ptr); j++) {
|
||||
if (i != j) {
|
||||
if (ptr[i] == ptr[j]) {
|
||||
fprintf(stderr, "ptrs[%d] == ptrs[%d].\n", i, j);
|
||||
return false;
|
||||
} else if (IN_RANGE(
|
||||
(char*)GET_MEM_NODE_HEADER(ptr[i]) + GET_MEM_NODE_HEADER(ptr[i])->size,
|
||||
(char*)GET_MEM_NODE_HEADER(ptr[i]),
|
||||
(char*)GET_MEM_NODE_HEADER(ptr[j]),
|
||||
GET_MEM_NODE_HEADER(ptr[j])->size)) {
|
||||
fprintf(stderr, "node %p in node %p", GET_MEM_NODE_HEADER(ptr[i]), GET_MEM_NODE_HEADER(ptr[j]));
|
||||
// additional info, may help with debug
|
||||
fprintf(stderr, "node %p\n size:%p\n free:%p\n next: %p\n last: %p\n", GET_MEM_NODE_HEADER(ptr[i]), GET_MEM_NODE_HEADER(ptr[i])->size, GET_MEM_NODE_HEADER(ptr[i])->free, GET_MEM_NODE_HEADER(ptr[i])->next, GET_MEM_NODE_HEADER(ptr[i])->last);
|
||||
fprintf(stderr, "node %p\n size:%p\n free:%p\n next: %p\n last: %p\n", GET_MEM_NODE_HEADER(ptr[j]), GET_MEM_NODE_HEADER(ptr[j])->size, GET_MEM_NODE_HEADER(ptr[j])->free, GET_MEM_NODE_HEADER(ptr[j])->next, GET_MEM_NODE_HEADER(ptr[j])->last);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) {
|
||||
free(ptr[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool test_malloc_data_integrity()
|
||||
{
|
||||
const char* As = "AAA";
|
||||
const char* Cs = "CCC";
|
||||
|
||||
char* A = (char*)malloc(10);
|
||||
char* B = (char*)malloc(10);
|
||||
char* C = (char*)malloc(10);
|
||||
|
||||
if (!A || !B || !C) {
|
||||
printf("can't alloc\n");
|
||||
free(A);
|
||||
free(B);
|
||||
free(C);
|
||||
return false;
|
||||
}
|
||||
|
||||
strcpy(A, As);
|
||||
strcpy(C, Cs);
|
||||
|
||||
free(B);
|
||||
|
||||
if (strcmp(A, As) != 0) {
|
||||
printf("A data is broken after free(B). A = '%s'\n", A);
|
||||
free(A);
|
||||
free(C);
|
||||
return false;
|
||||
}
|
||||
if (strcmp(C, Cs) != 0) {
|
||||
printf("C data is broken after free(B). C = '%s'\n", C);
|
||||
free(A);
|
||||
free(C);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(A);
|
||||
free(C);
|
||||
return true;
|
||||
}
|
||||
bool test_malloc_large_allocation()
|
||||
{
|
||||
void* ptr = malloc(1024 * 1024 * 16); // alloc 16mb
|
||||
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
bool test_malloc_allocation_and_free()
|
||||
{
|
||||
free(malloc(sizeof(int)));
|
||||
return true;
|
||||
}
|
||||
|
||||
void fill_buffer(void* ptr, size_t size, unsigned char pattern)
|
||||
{
|
||||
if (ptr) {
|
||||
memset(ptr, pattern, size);
|
||||
}
|
||||
}
|
||||
|
||||
bool check_buffer(void* ptr, size_t size, unsigned char pattern)
|
||||
{
|
||||
if (!ptr) {
|
||||
return false;
|
||||
}
|
||||
unsigned char* byte_ptr = (unsigned char*)ptr;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (byte_ptr[i] != pattern) {
|
||||
fprintf(stderr, "Error: Byte %u does not match pattern. Expected %02X, got %02X\n",
|
||||
i, pattern, byte_ptr[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_realloc_basic_grow()
|
||||
{
|
||||
size_t old_size = 10;
|
||||
size_t new_size = 20;
|
||||
int* ptr = (int*)malloc(old_size * sizeof(int));
|
||||
|
||||
if (ptr == NULL) {
|
||||
return false;
|
||||
}
|
||||
fill_buffer(ptr, old_size * sizeof(int), 0xAA);
|
||||
|
||||
int* new_ptr = (int*)realloc(ptr, new_size * sizeof(int));
|
||||
|
||||
if (new_ptr == NULL) {
|
||||
free(ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_buffer(new_ptr, old_size * sizeof(int), 0xAA)) {
|
||||
free(new_ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
fill_buffer(new_ptr + old_size, (new_size - old_size) * sizeof(int), 0xBB);
|
||||
if (!check_buffer(new_ptr + old_size, (new_size - old_size) * sizeof(int), 0xBB)) {
|
||||
free(new_ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(new_ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_realloc_basic_shrink()
|
||||
{
|
||||
size_t old_size = 20;
|
||||
size_t new_size = 10;
|
||||
int* ptr = (int*)malloc(old_size * sizeof(int));
|
||||
|
||||
if (ptr == NULL) {
|
||||
return false;
|
||||
}
|
||||
fill_buffer(ptr, old_size * sizeof(int), 0xCC);
|
||||
|
||||
int* new_ptr = (int*)realloc(ptr, new_size * sizeof(int));
|
||||
|
||||
if (new_ptr == NULL) {
|
||||
free(ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_buffer(new_ptr, new_size * sizeof(int), 0xCC)) {
|
||||
free(new_ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(new_ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_realloc_same_size()
|
||||
{
|
||||
size_t size = 15;
|
||||
int* ptr = (int*)malloc(size * sizeof(int));
|
||||
|
||||
if (ptr == NULL) {
|
||||
return false;
|
||||
}
|
||||
fill_buffer(ptr, size * sizeof(int), 0xDD);
|
||||
|
||||
int* new_ptr = (int*)realloc(ptr, size * sizeof(int));
|
||||
|
||||
if (new_ptr == NULL) {
|
||||
free(ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_buffer(new_ptr, size * sizeof(int), 0xDD)) {
|
||||
free(new_ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(new_ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_realloc_null_ptr()
|
||||
{
|
||||
size_t size = 25;
|
||||
void* ptr = realloc(NULL, size);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fill_buffer(ptr, size, 0xEE);
|
||||
if (!check_buffer(ptr, size, 0xEE)) {
|
||||
free(ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_realloc_to_zero_size()
|
||||
{
|
||||
size_t old_size = 30;
|
||||
void* ptr = malloc(old_size);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return false;
|
||||
}
|
||||
fill_buffer(ptr, old_size, 0xFF);
|
||||
|
||||
void* new_ptr = realloc(ptr, 0);
|
||||
|
||||
if (new_ptr == NULL) {
|
||||
printf("realloc(ptr, 0) return NULL.\n");
|
||||
free(ptr);
|
||||
} else {
|
||||
printf("realloc(ptr, 0) return: %p.\n", new_ptr);
|
||||
free(new_ptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
RUN_TEST(test_malloc_basic_allocation);
|
||||
RUN_TEST(test_malloc_zero_bytes);
|
||||
RUN_TEST(test_malloc_multiple_allocations);
|
||||
RUN_TEST(test_malloc_data_integrity);
|
||||
RUN_TEST(test_malloc_large_allocation);
|
||||
RUN_TEST(test_malloc_basic_allocation);
|
||||
RUN_TEST(test_malloc_allocation_and_free);
|
||||
RUN_TEST(test_realloc_basic_grow);
|
||||
RUN_TEST(test_realloc_basic_shrink);
|
||||
RUN_TEST(test_realloc_same_size);
|
||||
RUN_TEST(test_realloc_null_ptr);
|
||||
RUN_TEST(test_realloc_to_zero_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -19,9 +19,6 @@ FILE* out = stdout;
|
||||
FILE* out = stderr;
|
||||
#endif
|
||||
|
||||
#define EXIT_SUCCESS 0
|
||||
#define EXIT_FAILURE 1
|
||||
|
||||
#define fprintf fprintf
|
||||
|
||||
void show_help()
|
||||
|
||||
@@ -203,7 +203,6 @@ ksys_dll_t EXPORTS[] = {
|
||||
{ "strspn", &strspn },
|
||||
{ "strstr", &strstr },
|
||||
{ "strtok", &strtok },
|
||||
{ "strtok_r", &strtok_r },
|
||||
{ "strxfrm", &strxfrm },
|
||||
{ "strpbrk", &strpbrk },
|
||||
{ "__errno", &__errno },
|
||||
|
||||
81
programs/develop/ktcc/trunk/libc.obj/source/stdlib/_mem.h
Normal file
81
programs/develop/ktcc/trunk/libc.obj/source/stdlib/_mem.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#ifndef _LIBC_STDLIB__MEM_
|
||||
#define _LIBC_STDLIB__MEM_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct mem_node {
|
||||
size_t free; // Amount of free space in this node. When equal to size, the entire node is free.
|
||||
|
||||
size_t size; // Total size of this memory node.
|
||||
|
||||
struct mem_node* last; // Pointer to the previous memory node in the linked list.
|
||||
struct mem_node* next; // Pointer to the next memory node in the linked list.
|
||||
};
|
||||
|
||||
struct mem_block {
|
||||
size_t size; // Size of the allocated memory block.
|
||||
|
||||
size_t a; // align to 8bytes
|
||||
};
|
||||
|
||||
// Size of the blocks allocated by `_ksys_alloc`
|
||||
#define ALLOC_BLOCK_SIZE 4096
|
||||
|
||||
// Macro to get a pointer to the user data area from a mem_node pointer.
|
||||
// This is done by adding the size of the mem_node structure to the mem_node pointer.
|
||||
#define GET_MEM_NODE_PTR(node) (char*)((char*)(node) + sizeof(struct mem_node))
|
||||
|
||||
// Macro to check if a memory node is completely free.
|
||||
#define MEM_NODE_IS_FREE(node) (node->free == node->size)
|
||||
|
||||
// Macro to get the amount of used memory in a memory node.
|
||||
#define GET_MEM_NODE_USED_MEM(node) (node->size - node->free)
|
||||
|
||||
// Macro to get a pointer to the mem_node structure from a user data pointer.
|
||||
// This is done by subtracting the size of the mem_node structure from the user data pointer.
|
||||
#define GET_MEM_NODE_HEADER(ptr) ((struct mem_node*)(((char*)ptr) - sizeof(struct mem_node)))
|
||||
|
||||
// Macro to check if two adjacent memory nodes are in the same block.
|
||||
// Checks if the end of the left node's allocated space is the start of the right node.
|
||||
#define MEM_NODES_ARE_IN_ONE_BLOCK(left, right) (GET_MEM_NODE_PTR(left) + ((struct mem_node*)left)->size == (char*)right)
|
||||
|
||||
// Macro to merge two adjacent memory nodes.
|
||||
#define CHECK_SIDE_IN_OTHER_BLOCK(node, side) (side == NULL || ((side != NULL) && !MEM_NODES_ARE_IN_ONE_BLOCK(node, side)))
|
||||
|
||||
// align a value to a specified alignment.
|
||||
// Ensures that the allocated memory is aligned to a certain boundary
|
||||
inline size_t __mem_align(size_t value, size_t align)
|
||||
{
|
||||
return ((value + align - 1) & ~(align - 1));
|
||||
}
|
||||
|
||||
#define __mem_default_align(value) __mem_align(value, 8)
|
||||
|
||||
inline struct mem_node* __mem_MERGE_MEM_NODES(struct mem_node* base, struct mem_node* addition)
|
||||
{
|
||||
// addition is free && nodes base and addition both in one block, else merge is impossible
|
||||
if (MEM_NODE_IS_FREE(addition) && MEM_NODES_ARE_IN_ONE_BLOCK(base, addition)) {
|
||||
// just change size
|
||||
const size_t s = addition->size + sizeof(struct mem_node);
|
||||
base->size += s;
|
||||
base->free += s;
|
||||
|
||||
// and delete addition from list
|
||||
if (addition->next != NULL) {
|
||||
addition->next->last = base;
|
||||
base->next = addition->next;
|
||||
} else {
|
||||
base->next = NULL;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Static pointer to the first memory node in the linked list.
|
||||
// This acts as the head of the memory pool.
|
||||
static struct mem_node* __mem_node = NULL;
|
||||
|
||||
static struct mem_node* __last_biggest_mem_node = NULL;
|
||||
|
||||
#endif // _LIBC_STDLIB_MEM_
|
||||
@@ -1,14 +1,10 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ksys.h>
|
||||
|
||||
void* calloc(size_t num, size_t size)
|
||||
{
|
||||
void* ptr = _ksys_alloc(num * size);
|
||||
if (!ptr) {
|
||||
__errno = ENOMEM;
|
||||
return NULL;
|
||||
void* ptr = malloc(num * size);
|
||||
if (ptr) {
|
||||
memset(ptr, 0, num * size);
|
||||
}
|
||||
memset(ptr, 0, num * size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,103 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
* Copyright (C) 2026 KolibriOS team
|
||||
* Author: Yarin Egor<velikiydolbayeb@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/ksys.h>
|
||||
#include "_mem.h"
|
||||
|
||||
void free(void* ptr)
|
||||
{
|
||||
_ksys_free(ptr);
|
||||
}
|
||||
// Handle NULL pointer.
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
// Get a pointer to the mem_node header from the user data pointer.
|
||||
struct mem_node* node = GET_MEM_NODE_HEADER(ptr);
|
||||
|
||||
// Mark the memory node as free.
|
||||
node->free = node->size;
|
||||
|
||||
if (__last_biggest_mem_node == node) {
|
||||
if (node->last) {
|
||||
__last_biggest_mem_node = node->last; // anyway node will be merged with next
|
||||
// and last and last will have size = last + node + next(if its free too)
|
||||
}
|
||||
}
|
||||
|
||||
// Merge with the next node if possible.
|
||||
if (node->next != NULL)
|
||||
__mem_MERGE_MEM_NODES(node, node->next);
|
||||
|
||||
// Merge with the previous node if possible.
|
||||
if (node->last != NULL)
|
||||
node = __mem_MERGE_MEM_NODES(node->last, node);
|
||||
|
||||
if (node) {
|
||||
|
||||
// If the current node is not adjacent to either the next or previous node,
|
||||
// it might be a separate block that can be freed.
|
||||
if (MEM_NODE_IS_FREE(node) // check it because node maybe was merged with last
|
||||
&& (node->last == NULL || !MEM_NODES_ARE_IN_ONE_BLOCK(node, node->next))
|
||||
&& (node->next == NULL || !MEM_NODES_ARE_IN_ONE_BLOCK(node->last, node))) {
|
||||
|
||||
// Get a pointer to the mem_block header from the mem_node header.
|
||||
struct mem_block* block = (struct mem_block*)(((char*)node) - sizeof(struct mem_block));
|
||||
|
||||
// Check if the block size matches the node size.
|
||||
if (block->size == node->size + sizeof(struct mem_block) + sizeof(struct mem_node)) {
|
||||
|
||||
// Update the linked list pointers to remove the current node.
|
||||
if (node->last != NULL)
|
||||
node->last->next = node->next;
|
||||
|
||||
if (node->next != NULL)
|
||||
node->next->last = node->last;
|
||||
|
||||
// Update the head of the linked list if necessary.
|
||||
if (__mem_node == node) {
|
||||
if (node->last != NULL) {
|
||||
__mem_node = node->last;
|
||||
} else if (node->next != NULL) {
|
||||
__mem_node = node->next;
|
||||
} else {
|
||||
__mem_node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct mem_node* a = node->next;
|
||||
struct mem_node* b = node->last;
|
||||
|
||||
if (!a && !b) {
|
||||
__last_biggest_mem_node = NULL;
|
||||
} else if (a && !b) {
|
||||
__last_biggest_mem_node = a;
|
||||
} else if (!a && b) {
|
||||
__last_biggest_mem_node = b;
|
||||
} else if (a && b) {
|
||||
__last_biggest_mem_node = (a->free > b->free) ? a : b;
|
||||
}
|
||||
|
||||
if (__last_biggest_mem_node == node) {
|
||||
if (node->next && !(node->last)) {
|
||||
__last_biggest_mem_node = node->next;
|
||||
} else if (node->last && !(node->next)) {
|
||||
__last_biggest_mem_node = node->last;
|
||||
} else if (node->next && node->last) {
|
||||
if (node->last->free > node->next->free) {
|
||||
__last_biggest_mem_node = node->last;
|
||||
} else {
|
||||
__last_biggest_mem_node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Free the memory block using the ksys_free function.
|
||||
_ksys_free(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,132 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
* Copyright (C) 2026 KolibriOS team
|
||||
* Author: Yarin Egor<velikiydolbayeb@gmail.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ksys.h>
|
||||
#include <stdbool.h>
|
||||
#include "_mem.h"
|
||||
|
||||
static struct mem_node* __new_mem_node_from_exist(struct mem_node* current_node, size_t size, bool* from_empty_node)
|
||||
{
|
||||
struct mem_node* new_node = NULL;
|
||||
// Check if the current node has enough free space for the requested size.
|
||||
if (size + sizeof(struct mem_node) <= current_node->free) {
|
||||
|
||||
*from_empty_node = MEM_NODE_IS_FREE(current_node);
|
||||
if (*from_empty_node) {
|
||||
new_node = current_node;
|
||||
} else {
|
||||
// Calculate the used memory in current node
|
||||
const size_t s = GET_MEM_NODE_USED_MEM(current_node);
|
||||
|
||||
// Create a new memory node after the current node's used space.
|
||||
new_node = (struct mem_node*)(GET_MEM_NODE_PTR(current_node) + s);
|
||||
|
||||
// Update current node's size
|
||||
current_node->size = s;
|
||||
|
||||
// Set the size of the new node.
|
||||
// for new node give all free space in current node
|
||||
new_node->size = current_node->free - sizeof(struct mem_node);
|
||||
|
||||
// Mark current node as used.
|
||||
current_node->free = 0;
|
||||
}
|
||||
}
|
||||
return new_node;
|
||||
}
|
||||
|
||||
void* malloc(size_t size)
|
||||
{
|
||||
return _ksys_alloc(size);
|
||||
}
|
||||
// Handle zero-size allocation.
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Align the size to 8 bytes.
|
||||
size = __mem_default_align(size);
|
||||
|
||||
struct mem_node* current_node = __mem_node;
|
||||
struct mem_node* new_node = NULL; // Pointer to the new node that will be created.
|
||||
bool from_empty_node = false;
|
||||
|
||||
if (__last_biggest_mem_node != NULL)
|
||||
new_node = __new_mem_node_from_exist(__last_biggest_mem_node, size, &from_empty_node); // try find free space in last created node
|
||||
|
||||
// if cant find in __last_biggest_mem_node
|
||||
if (new_node == NULL) {
|
||||
// Iterate through the linked list of memory nodes.
|
||||
while (current_node != NULL) {
|
||||
new_node = __new_mem_node_from_exist(current_node, size, &from_empty_node);
|
||||
if (new_node)
|
||||
break; // Found a suitable node, exit the loop.
|
||||
|
||||
current_node = current_node->next; // Move to the next node in the list.
|
||||
}
|
||||
}
|
||||
|
||||
// If no suitable node was found in the existing list:
|
||||
if (new_node == NULL) {
|
||||
// Calculate the size of the new block, including the mem_block header, mem_node header and alignment.
|
||||
const size_t s = __mem_align(size + sizeof(struct mem_block) + sizeof(struct mem_node), ALLOC_BLOCK_SIZE);
|
||||
|
||||
// Allocate a new block of memory using the ksys_alloc function (presumably a kernel-level allocation function).
|
||||
struct mem_block* block = (struct mem_block*)_ksys_alloc(s);
|
||||
|
||||
// Check if the allocation was successful.
|
||||
if (block == NULL) {
|
||||
__errno = ENOMEM; // Set the error number to indicate memory allocation failure.
|
||||
return NULL; // Return NULL to indicate allocation failure.
|
||||
}
|
||||
|
||||
block->size = s;
|
||||
|
||||
// Create a new memory node after the mem_block header.
|
||||
new_node = (struct mem_node*)(((char*)block) + sizeof(struct mem_block));
|
||||
|
||||
// Set the size of the new node.
|
||||
new_node->size = s - sizeof(struct mem_block) - sizeof(struct mem_node);
|
||||
}
|
||||
|
||||
// Set the free space in the new node.
|
||||
new_node->free = new_node->size - size;
|
||||
|
||||
if (!from_empty_node) {
|
||||
// Set the last pointer of the new node to the current node.
|
||||
new_node->last = current_node;
|
||||
|
||||
// Link the new node into the linked list.
|
||||
if (current_node != NULL) {
|
||||
// Set the next pointer of the current node to the new node.
|
||||
new_node->next = current_node->next;
|
||||
|
||||
// Update the last pointer of the next node, if it exists.
|
||||
if (current_node->next != NULL) {
|
||||
current_node->next->last = new_node;
|
||||
}
|
||||
current_node->next = new_node;
|
||||
} else {
|
||||
// If the current node is NULL, the new node is the first node in the list.
|
||||
new_node->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// If the linked list was empty, set the head to the new node.
|
||||
if (__mem_node == NULL) {
|
||||
__mem_node = new_node;
|
||||
}
|
||||
|
||||
if (__last_biggest_mem_node == NULL || new_node->free > __last_biggest_mem_node->free) {
|
||||
__last_biggest_mem_node = new_node;
|
||||
}
|
||||
|
||||
// Return a pointer to the user data area of the new node.
|
||||
return GET_MEM_NODE_PTR(new_node);
|
||||
}
|
||||
|
||||
#undef __mem_align
|
||||
|
||||
@@ -1,7 +1,82 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
* Copyright (C) 2026 KolibriOS team
|
||||
* Author: Yarin Egor<velikiydolbayeb@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ksys.h>
|
||||
#include "_mem.h"
|
||||
|
||||
// realloc mem. using if other ways not working
|
||||
static void* fail_realloc(void* ptr, size_t newsize)
|
||||
{
|
||||
// Allocate a new block of memory with the new size.
|
||||
void* new_ptr = malloc(newsize);
|
||||
|
||||
// If both the old pointer and the new pointer are not NULL:
|
||||
if (ptr != NULL && new_ptr != NULL) {
|
||||
// Copy the data from the old block to the new block.
|
||||
memcpy(new_ptr, ptr, min(newsize, GET_MEM_NODE_USED_MEM(GET_MEM_NODE_HEADER(ptr))));
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
free(ptr); // Free the old block.
|
||||
}
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void* realloc(void* ptr, size_t newsize)
|
||||
{
|
||||
return _ksys_realloc(ptr, newsize);
|
||||
}
|
||||
|
||||
void* new_ptr = NULL;
|
||||
struct mem_node* node = NULL;
|
||||
|
||||
if (ptr && newsize) {
|
||||
|
||||
// Get a pointer to the mem_node header from the user data pointer.
|
||||
node = GET_MEM_NODE_HEADER(ptr);
|
||||
|
||||
newsize = __mem_default_align(newsize);
|
||||
|
||||
if (node->size >= newsize) { // current node have enough mem
|
||||
// it work always if newsize is smaller
|
||||
// Update the free space in the current node.
|
||||
node->free = node->size - newsize;
|
||||
// Return the original pointer.
|
||||
new_ptr = ptr;
|
||||
} else if (node->last && MEM_NODE_IS_FREE(node->last) && node->size + node->last->size >= newsize) {
|
||||
// So what happens here is that the node merges with the last node if their volume is sufficient.
|
||||
// And a reallock is called in the hopes that the first condition will be met.
|
||||
// if merge failed realloc anyway return pointer, but it will got from `fail_realloc`
|
||||
struct mem_node* l = node->last;
|
||||
|
||||
l = __mem_MERGE_MEM_NODES(l, node);
|
||||
if (l) {
|
||||
memmove(GET_MEM_NODE_PTR(l), ptr, GET_MEM_NODE_USED_MEM(node));
|
||||
new_ptr = realloc(GET_MEM_NODE_PTR(l), newsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (new_ptr == NULL) {
|
||||
|
||||
// Allocate a new block of memory with the new size.
|
||||
new_ptr = malloc(newsize);
|
||||
|
||||
// If both the old pointer and the new pointer are not NULL:
|
||||
if (ptr != NULL && new_ptr != NULL) {
|
||||
// Copy the data from the old block to the new block.
|
||||
memcpy(new_ptr, ptr, min(newsize, GET_MEM_NODE_USED_MEM(GET_MEM_NODE_HEADER(ptr))));
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
free(ptr); // Free the old block.
|
||||
}
|
||||
}
|
||||
|
||||
// Return the new pointer.
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
|
||||
#include <string.h>
|
||||
|
||||
char* strtok_r(char* s, const char* delim, char** last)
|
||||
char* strtok(char* s, const char* delim)
|
||||
{
|
||||
char *spanp, *tok;
|
||||
const char* spanp;
|
||||
int c, sc;
|
||||
char* tok;
|
||||
static char* last;
|
||||
|
||||
if (s == NULL && (s = *last) == NULL)
|
||||
if (s == NULL && (s = last) == NULL)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
@@ -14,13 +16,13 @@ char* strtok_r(char* s, const char* delim, char** last)
|
||||
*/
|
||||
cont:
|
||||
c = *s++;
|
||||
for (spanp = (char*)delim; (sc = *spanp++) != 0;) {
|
||||
for (spanp = delim; (sc = *spanp++) != 0;) {
|
||||
if (c == sc)
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (c == 0) { /* no non-delimiter characters */
|
||||
*last = NULL;
|
||||
last = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
tok = s - 1;
|
||||
@@ -31,24 +33,17 @@ cont:
|
||||
*/
|
||||
for (;;) {
|
||||
c = *s++;
|
||||
spanp = (char*)delim;
|
||||
spanp = delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0)
|
||||
s = NULL;
|
||||
else
|
||||
s[-1] = '\0';
|
||||
*last = s;
|
||||
s[-1] = 0;
|
||||
last = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
char *strtok(char *s, const char *delim)
|
||||
{
|
||||
static char *last;
|
||||
|
||||
return (strtok_r(s, delim, &last));
|
||||
}
|
||||
|
||||
19
programs/develop/libraries/microtar/LICENSE
Normal file
19
programs/develop/libraries/microtar/LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2017 rxi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
99
programs/develop/libraries/microtar/README.md
Normal file
99
programs/develop/libraries/microtar/README.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# microtar
|
||||
A lightweight tar library written in ANSI C
|
||||
|
||||
|
||||
## Basic Usage
|
||||
The library consists of `microtar.c` and `microtar.h`. These two files can be
|
||||
dropped into an existing project and compiled along with it.
|
||||
|
||||
|
||||
#### Reading
|
||||
```c
|
||||
mtar_t tar;
|
||||
mtar_header_t h;
|
||||
char *p;
|
||||
|
||||
/* Open archive for reading */
|
||||
mtar_open(&tar, "test.tar", "r");
|
||||
|
||||
/* Print all file names and sizes */
|
||||
while ( (mtar_read_header(&tar, &h)) != MTAR_ENULLRECORD ) {
|
||||
printf("%s (%d bytes)\n", h.name, h.size);
|
||||
mtar_next(&tar);
|
||||
}
|
||||
|
||||
/* Load and print contents of file "test.txt" */
|
||||
mtar_find(&tar, "test.txt", &h);
|
||||
p = calloc(1, h.size + 1);
|
||||
mtar_read_data(&tar, p, h.size);
|
||||
printf("%s", p);
|
||||
free(p);
|
||||
|
||||
/* Close archive */
|
||||
mtar_close(&tar);
|
||||
```
|
||||
|
||||
#### Writing
|
||||
```c
|
||||
mtar_t tar;
|
||||
const char *str1 = "Hello world";
|
||||
const char *str2 = "Goodbye world";
|
||||
|
||||
/* Open archive for writing */
|
||||
mtar_open(&tar, "test.tar", "w");
|
||||
|
||||
/* Write strings to files `test1.txt` and `test2.txt` */
|
||||
mtar_write_file_header(&tar, "test1.txt", strlen(str1));
|
||||
mtar_write_data(&tar, str1, strlen(str1));
|
||||
mtar_write_file_header(&tar, "test2.txt", strlen(str2));
|
||||
mtar_write_data(&tar, str2, strlen(str2));
|
||||
|
||||
/* Finalize -- this needs to be the last thing done before closing */
|
||||
mtar_finalize(&tar);
|
||||
|
||||
/* Close archive */
|
||||
mtar_close(&tar);
|
||||
```
|
||||
|
||||
|
||||
## Error handling
|
||||
All functions which return an `int` will return `MTAR_ESUCCESS` if the operation
|
||||
is successful. If an error occurs an error value less-than-zero will be
|
||||
returned; this value can be passed to the function `mtar_strerror()` to get its
|
||||
corresponding error string.
|
||||
|
||||
|
||||
## Wrapping a stream
|
||||
If you want to read or write from something other than a file, the `mtar_t`
|
||||
struct can be manually initialized with your own callback functions and a
|
||||
`stream` pointer.
|
||||
|
||||
All callback functions are passed a pointer to the `mtar_t` struct as their
|
||||
first argument. They should return `MTAR_ESUCCESS` if the operation succeeds
|
||||
without an error, or an integer below zero if an error occurs.
|
||||
|
||||
After the `stream` field has been set, all required callbacks have been set and
|
||||
all unused fields have been zeroset the `mtar_t` struct can be safely used with
|
||||
the microtar functions. `mtar_open` *should not* be called if the `mtar_t`
|
||||
struct was initialized manually.
|
||||
|
||||
#### Reading
|
||||
The following callbacks should be set for reading an archive from a stream:
|
||||
|
||||
Name | Arguments | Description
|
||||
--------|------------------------------------------|---------------------------
|
||||
`read` | `mtar_t *tar, void *data, unsigned size` | Read data from the stream
|
||||
`seek` | `mtar_t *tar, unsigned pos` | Set the position indicator
|
||||
`close` | `mtar_t *tar` | Close the stream
|
||||
|
||||
#### Writing
|
||||
The following callbacks should be set for writing an archive to a stream:
|
||||
|
||||
Name | Arguments | Description
|
||||
--------|------------------------------------------------|---------------------
|
||||
`write` | `mtar_t *tar, const void *data, unsigned size` | Write data to the stream
|
||||
|
||||
|
||||
## License
|
||||
This library is free software; you can redistribute it and/or modify it under
|
||||
the terms of the MIT license. See [LICENSE](LICENSE) for details.
|
||||
8
programs/develop/libraries/microtar/Tupfile.lua
Executable file
8
programs/develop/libraries/microtar/Tupfile.lua
Executable file
@@ -0,0 +1,8 @@
|
||||
if tup.getconfig("NO_GCC") ~= "" then return end
|
||||
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../../../" or tup.getconfig("HELPERDIR")
|
||||
tup.include(HELPERDIR .. "/use_gcc.lua")
|
||||
|
||||
CFLAGS = " -c -w -nostdinc -DGNUC -DMTAR_OBJ -Os -fno-common -fno-builtin -fno-leading-underscore -fno-pie"
|
||||
INCLUDES = " -I../include -I../../ktcc/trunk/libc.obj/include"
|
||||
|
||||
tup.rule("microtar.c", "kos32-gcc" .. CFLAGS .. INCLUDES .. " -o %o %f " .. tup.getconfig("KPACK_CMD"), "mtar.obj")
|
||||
78
programs/develop/libraries/microtar/example/read.asm
Normal file
78
programs/develop/libraries/microtar/example/read.asm
Normal file
@@ -0,0 +1,78 @@
|
||||
format binary as "kex"
|
||||
|
||||
use32
|
||||
org 0x0
|
||||
db 'MENUET01'
|
||||
dd 0x01
|
||||
dd START
|
||||
dd IM_END
|
||||
dd MEM
|
||||
dd MEM
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
include '../../../../macros.inc'
|
||||
include '../../../../proc32.inc'
|
||||
include '../../../../KOSfuncs.inc'
|
||||
include '../../../../dll.inc'
|
||||
include '../mtar.inc'
|
||||
;include '../../../../debug-fdo.inc'
|
||||
|
||||
;__DEBUG__ = 1
|
||||
;__DEBUG_LEVEL__ = 2
|
||||
|
||||
|
||||
START:
|
||||
stdcall dll.Load, @IMPORT ; Имортироуем функции из mtar.obj
|
||||
test eax, eax
|
||||
jnz exit
|
||||
|
||||
ccall [mtar_init] ; Инициализируем библиотеку (на самом деле подгружается libc.obj
|
||||
ccall [mtar_open], tar, tar_fname, tar_fmode ; Открываем для чтения файл 'test.tar'
|
||||
|
||||
; DEBUGF 2, "%d", eax
|
||||
|
||||
print_next:
|
||||
ccall [mtar_read_header], tar, header ; Читаем заголовок
|
||||
cmp eax, MTAR_ENULLRECORD ; Если заголовок не был прочитан (return -7) выходим из цикла
|
||||
je exit
|
||||
ccall [printf], format_str, header+mtar_header_t.name, dword[header+mtar_header_t.size] ; Выводим в консоль имя файла и размер в байтах
|
||||
ccall [mtar_next], tar ; Переходим к следующему заголовку
|
||||
jmp print_next ; прыгаем в начало цикла
|
||||
|
||||
exit:
|
||||
ccall [mtar_close], tar ; Закрываем 'test.tar'
|
||||
mcall SF_TERMINATE_PROCESS ; Выходим из программы
|
||||
|
||||
; data
|
||||
|
||||
tar_fname db 'test.tar', 0
|
||||
tar_fmode db 'r', 0
|
||||
|
||||
tar rb sizeof.mtar_t
|
||||
header rb sizeof.mtar_header_t
|
||||
|
||||
format_str db '%-10s (%-4d bytes)', 0x0A,0
|
||||
|
||||
align 4
|
||||
|
||||
@IMPORT:
|
||||
library mtar, 'mtar.obj', libc , 'libc.obj'
|
||||
import mtar, \
|
||||
mtar_init, 'mtar_init', \
|
||||
mtar_open, 'mtar_open', \
|
||||
mtar_next, 'mtar_next', \
|
||||
mtar_strerror, 'mtar_strerror', \
|
||||
mtar_read_header, 'mtar_read_header', \
|
||||
mtar_write_data, 'mtar_write_data', \
|
||||
mtar_finalize, 'mtar_finalize', \
|
||||
mtar_close, 'mtar_close'
|
||||
|
||||
import libc, \
|
||||
printf, 'printf'
|
||||
|
||||
|
||||
IM_END:
|
||||
align 4
|
||||
rb 4096 ; stack
|
||||
MEM:
|
||||
70
programs/develop/libraries/microtar/example/write.asm
Normal file
70
programs/develop/libraries/microtar/example/write.asm
Normal file
@@ -0,0 +1,70 @@
|
||||
format binary as "kex"
|
||||
|
||||
use32
|
||||
org 0x0
|
||||
db 'MENUET01'
|
||||
dd 0x01
|
||||
dd START
|
||||
dd IM_END
|
||||
dd MEM
|
||||
dd MEM
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
include '../../../../macros.inc'
|
||||
include '../../../../proc32.inc'
|
||||
include '../../../../KOSfuncs.inc'
|
||||
include '../../../../dll.inc'
|
||||
include '../mtar.inc'
|
||||
;include '../../../../debug-fdo.inc'
|
||||
|
||||
;__DEBUG__ = 1
|
||||
;__DEBUG_LEVEL__ = 2
|
||||
|
||||
START:
|
||||
stdcall dll.Load, @IMPORT ; Имортироуем функции из mtar.obj
|
||||
test eax, eax
|
||||
jnz exit
|
||||
|
||||
ccall [mtar_init] ; Инициализируем библиотеку (на самом деле подгружается libc.obj
|
||||
ccall [mtar_open], tar, tar_fname, tar_fmode ; Создаём новый файл 'test.tar'
|
||||
ccall [mtar_write_file_header], tar, test1_txt , str1_len ; Создаём внутри 'test.tar' пустрой файл 'test1.txt'
|
||||
|
||||
ccall [mtar_write_data], tar, str1, str1_len ; Записываем данныев в этот файл
|
||||
|
||||
ccall [mtar_finalize], tar ; Указываем что больше с tar работать не будем
|
||||
ccall [mtar_close], tar ; Закрываем 'test.tar'
|
||||
|
||||
exit:
|
||||
mcall SF_TERMINATE_PROCESS ; Выходим из программы
|
||||
|
||||
; data
|
||||
|
||||
str1 db 'Hello world!', 0
|
||||
str1_len = $ - str1
|
||||
|
||||
str2 db 'Goodbye world!', 0
|
||||
|
||||
tar_fname db 'test.tar', 0
|
||||
tar_fmode db 'w', 0
|
||||
|
||||
test1_txt db 'test1.txt', 0
|
||||
|
||||
tar rb 32
|
||||
|
||||
align 4
|
||||
|
||||
@IMPORT:
|
||||
library mtar, 'mtar.obj'
|
||||
import mtar, \
|
||||
mtar_init, 'mtar_init', \
|
||||
mtar_open, 'mtar_open', \
|
||||
mtar_write_file_header, 'mtar_write_file_header', \
|
||||
mtar_write_data, 'mtar_write_data', \
|
||||
mtar_finalize, 'mtar_finalize', \
|
||||
mtar_close, 'mtar_close'
|
||||
|
||||
IM_END:
|
||||
align 4
|
||||
rb 4096 ; stack
|
||||
MEM:
|
||||
450
programs/develop/libraries/microtar/microtar.c
Normal file
450
programs/develop/libraries/microtar/microtar.c
Normal file
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
* Copyright (c) 2017 rxi
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/ksys.h>
|
||||
|
||||
#include "microtar.h"
|
||||
|
||||
typedef struct {
|
||||
char name[100];
|
||||
char mode[8];
|
||||
char owner[8];
|
||||
char group[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char checksum[8];
|
||||
char type;
|
||||
char linkname[100];
|
||||
char _padding[255];
|
||||
} mtar_raw_header_t;
|
||||
|
||||
static void * mtar_memset( void * s, int c, size_t n ){
|
||||
unsigned char * p = ( unsigned char * ) s;
|
||||
while ( n-- ){
|
||||
*p++ = ( unsigned char ) c;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef MTAR_OBJ
|
||||
// All pointers was changed for compatible to latest version tcc and the libc.obj headers
|
||||
size_t (*_fread)(void *restrict, size_t size, size_t count, FILE *restrict)=NULL;
|
||||
size_t (*_fwrite)(const void *restrict, size_t size, size_t count, FILE *restrict)=NULL;
|
||||
int (*_fclose)(FILE *)=NULL;
|
||||
FILE* (*_fopen)(const char *restrict, const char *restrict)=NULL;
|
||||
int (*_fseek)(FILE *, long, int)=NULL;
|
||||
long (*_ftell)(FILE *)=NULL;
|
||||
int (*_sprintf)(char* buffer, const char* format, ...)=NULL;
|
||||
int (*_sscanf)(const char*, const char *restrict, ...)=NULL;
|
||||
int (*_strcmp)(const char * s1, const char* s2)=NULL;
|
||||
char* (*_strchr)(const char* s, int c)=NULL;
|
||||
char* (*_strcpy)(char* s1, const char* s2)=NULL;
|
||||
|
||||
#endif
|
||||
|
||||
static unsigned round_up(unsigned n, unsigned incr) {
|
||||
return n + (incr - n % incr) % incr;
|
||||
}
|
||||
|
||||
|
||||
static unsigned checksum(const mtar_raw_header_t* rh) {
|
||||
unsigned i;
|
||||
unsigned char *p = (unsigned char*) rh;
|
||||
unsigned res = 256;
|
||||
for (i = 0; i < offsetof(mtar_raw_header_t, checksum); i++) {
|
||||
res += p[i];
|
||||
}
|
||||
for (i = offsetof(mtar_raw_header_t, type); i < sizeof(*rh); i++) {
|
||||
res += p[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int tread(mtar_t *tar, void *data, unsigned size) {
|
||||
int err = tar->read(tar, data, size);
|
||||
tar->pos += size;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int twrite(mtar_t *tar, const void *data, unsigned size) {
|
||||
|
||||
int err = tar->write(tar, data, size);
|
||||
tar->pos += size;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int write_null_bytes(mtar_t *tar, int n) {
|
||||
int i, err;
|
||||
char nul = '\0';
|
||||
for (i = 0; i < n; i++) {
|
||||
err = twrite(tar, &nul, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return MTAR_ESUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int raw_to_header(mtar_header_t *h, const mtar_raw_header_t *rh) {
|
||||
unsigned chksum1, chksum2;
|
||||
|
||||
/* If the checksum starts with a null byte we assume the record is NULL */
|
||||
if (*rh->checksum == '\0') {
|
||||
return MTAR_ENULLRECORD;
|
||||
}
|
||||
|
||||
/* Build and compare checksum */
|
||||
chksum1 = checksum(rh);
|
||||
_sscanf(rh->checksum, "%o", &chksum2);
|
||||
if (chksum1 != chksum2) {
|
||||
return MTAR_EBADCHKSUM;
|
||||
}
|
||||
|
||||
/* Load raw header into header */
|
||||
_sscanf(rh->mode, "%o", &h->mode);
|
||||
_sscanf(rh->owner, "%o", &h->owner);
|
||||
_sscanf(rh->size, "%o", &h->size);
|
||||
_sscanf(rh->mtime, "%o", &h->mtime);
|
||||
h->type = rh->type;
|
||||
_strcpy(h->name, rh->name);
|
||||
_strcpy(h->linkname, rh->linkname);
|
||||
|
||||
return MTAR_ESUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int header_to_raw(mtar_raw_header_t *rh, const mtar_header_t *h) {
|
||||
unsigned chksum;
|
||||
|
||||
/* Load header into raw header */
|
||||
mtar_memset(rh, 0, sizeof(*rh));
|
||||
_sprintf(rh->mode, "%o", h->mode);
|
||||
_sprintf(rh->owner, "%o", h->owner);
|
||||
_sprintf(rh->size, "%o", h->size);
|
||||
_sprintf(rh->mtime, "%o", h->mtime);
|
||||
rh->type = h->type ? h->type : MTAR_TREG;
|
||||
_strcpy(rh->name, h->name);
|
||||
_strcpy(rh->linkname, h->linkname);
|
||||
|
||||
/* Calculate and write checksum */
|
||||
chksum = checksum(rh);
|
||||
_sprintf(rh->checksum, "%06o", chksum);
|
||||
rh->checksum[7] = ' ';
|
||||
|
||||
return MTAR_ESUCCESS;
|
||||
}
|
||||
|
||||
|
||||
const char* mtar_strerror(int err) {
|
||||
switch (err) {
|
||||
case MTAR_ESUCCESS : return "success";
|
||||
case MTAR_EFAILURE : return "failure";
|
||||
case MTAR_EOPENFAIL : return "could not open";
|
||||
case MTAR_EREADFAIL : return "could not read";
|
||||
case MTAR_EWRITEFAIL : return "could not write";
|
||||
case MTAR_ESEEKFAIL : return "could not seek";
|
||||
case MTAR_EBADCHKSUM : return "bad checksum";
|
||||
case MTAR_ENULLRECORD : return "null record";
|
||||
case MTAR_ENOTFOUND : return "file not found";
|
||||
}
|
||||
return "unknown error";
|
||||
}
|
||||
|
||||
|
||||
static int file_write(mtar_t *tar, const void *data, unsigned size) {
|
||||
unsigned res = _fwrite(data, 1, size, tar->stream);
|
||||
return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL;
|
||||
}
|
||||
|
||||
static int file_read(mtar_t *tar, void *data, unsigned size) {
|
||||
unsigned res = _fread(data, 1, size, tar->stream);
|
||||
return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL;
|
||||
}
|
||||
|
||||
static int file_seek(mtar_t *tar, unsigned offset) {
|
||||
int res = _fseek(tar->stream, offset, SEEK_SET);
|
||||
return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
|
||||
}
|
||||
|
||||
static int file_close(mtar_t *tar) {
|
||||
_fclose(tar->stream);
|
||||
return MTAR_ESUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int mtar_open(mtar_t *tar, const char *filename, const char *mode) {
|
||||
int err;
|
||||
mtar_header_t h;
|
||||
|
||||
/* Init tar struct and functions */
|
||||
mtar_memset(tar, 0, sizeof(*tar));
|
||||
tar->write = file_write;
|
||||
tar->read = file_read;
|
||||
tar->seek = file_seek;
|
||||
tar->close = file_close;
|
||||
|
||||
/* Assure mode is always binary */
|
||||
if ( _strchr(mode, 'r') ) mode = "rb";
|
||||
if ( _strchr(mode, 'w') ) mode = "wb";
|
||||
if ( _strchr(mode, 'a') ) mode = "ab";
|
||||
/* Open file */
|
||||
tar->stream = _fopen(filename, mode);
|
||||
if (!tar->stream) {
|
||||
return MTAR_EOPENFAIL;
|
||||
}
|
||||
/* Read first header to check it is valid if mode is `r` */
|
||||
if (*mode == 'r') {
|
||||
err = mtar_read_header(tar, &h);
|
||||
if (err != MTAR_ESUCCESS) {
|
||||
mtar_close(tar);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return ok */
|
||||
return MTAR_ESUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int mtar_close(mtar_t *tar) {
|
||||
return tar->close(tar);
|
||||
}
|
||||
|
||||
|
||||
int mtar_seek(mtar_t *tar, unsigned pos) {
|
||||
int err = tar->seek(tar, pos);
|
||||
tar->pos = pos;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int mtar_rewind(mtar_t *tar) {
|
||||
tar->remaining_data = 0;
|
||||
tar->last_header = 0;
|
||||
return mtar_seek(tar, 0);
|
||||
}
|
||||
|
||||
|
||||
int mtar_next(mtar_t *tar) {
|
||||
int err, n;
|
||||
mtar_header_t h;
|
||||
/* Load header */
|
||||
err = mtar_read_header(tar, &h);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
/* Seek to next record */
|
||||
n = round_up(h.size, 512) + sizeof(mtar_raw_header_t);
|
||||
return mtar_seek(tar, tar->pos + n);
|
||||
}
|
||||
|
||||
|
||||
int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h) {
|
||||
int err;
|
||||
mtar_header_t header;
|
||||
/* Start at beginning */
|
||||
err = mtar_rewind(tar);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
/* Iterate all files until we hit an error or find the file */
|
||||
while ( (err = mtar_read_header(tar, &header)) == MTAR_ESUCCESS ) {
|
||||
if ( !_strcmp(header.name, name) ) {
|
||||
if (h) {
|
||||
*h = header;
|
||||
}
|
||||
return MTAR_ESUCCESS;
|
||||
}
|
||||
mtar_next(tar);
|
||||
}
|
||||
/* Return error */
|
||||
if (err == MTAR_ENULLRECORD) {
|
||||
err = MTAR_ENOTFOUND;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int mtar_read_header(mtar_t *tar, mtar_header_t *h) {
|
||||
int err;
|
||||
mtar_raw_header_t rh;
|
||||
/* Save header position */
|
||||
tar->last_header = tar->pos;
|
||||
/* Read raw header */
|
||||
err = tread(tar, &rh, sizeof(rh));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
/* Seek back to start of header */
|
||||
err = mtar_seek(tar, tar->last_header);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
/* Load raw header into header struct and return */
|
||||
return raw_to_header(h, &rh);
|
||||
}
|
||||
|
||||
|
||||
int mtar_read_data(mtar_t *tar, void *ptr, unsigned size) {
|
||||
int err;
|
||||
/* If we have no remaining data then this is the first read, we get the size,
|
||||
* set the remaining data and seek to the beginning of the data */
|
||||
if (tar->remaining_data == 0) {
|
||||
mtar_header_t h;
|
||||
/* Read header */
|
||||
err = mtar_read_header(tar, &h);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
/* Seek past header and init remaining data */
|
||||
err = mtar_seek(tar, tar->pos + sizeof(mtar_raw_header_t));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
tar->remaining_data = h.size;
|
||||
}
|
||||
/* Read data */
|
||||
err = tread(tar, ptr, size);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
tar->remaining_data -= size;
|
||||
/* If there is no remaining data we've finished reading and seek back to the
|
||||
* header */
|
||||
if (tar->remaining_data == 0) {
|
||||
return mtar_seek(tar, tar->last_header);
|
||||
}
|
||||
return MTAR_ESUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int mtar_write_header(mtar_t *tar, const mtar_header_t *h) {
|
||||
mtar_raw_header_t rh;
|
||||
/* Build raw header and write */
|
||||
header_to_raw(&rh, h);
|
||||
tar->remaining_data = h->size;
|
||||
return twrite(tar, &rh, sizeof(rh));
|
||||
}
|
||||
|
||||
int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size) {
|
||||
mtar_header_t h;
|
||||
/* Build header */
|
||||
mtar_memset(&h, 0, sizeof(h));
|
||||
_strcpy(h.name, name);
|
||||
h.size = size;
|
||||
h.type = MTAR_TREG;
|
||||
h.mode = 0664;
|
||||
/* Write header */
|
||||
return mtar_write_header(tar, &h);
|
||||
}
|
||||
|
||||
|
||||
int mtar_write_dir_header(mtar_t *tar, const char *name) {
|
||||
mtar_header_t h;
|
||||
/* Build header */
|
||||
mtar_memset(&h, 0, sizeof(h));
|
||||
_strcpy(h.name, name);
|
||||
h.type = MTAR_TDIR;
|
||||
h.mode = 0775;
|
||||
/* Write header */
|
||||
return mtar_write_header(tar, &h);
|
||||
}
|
||||
|
||||
|
||||
int mtar_write_data(mtar_t *tar, const void *data, unsigned size) {
|
||||
int err;
|
||||
/* Write data */
|
||||
err = twrite(tar, data, size);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
tar->remaining_data -= size;
|
||||
/* Write padding if we've written all the data for this file */
|
||||
if (tar->remaining_data == 0) {
|
||||
return write_null_bytes(tar, round_up(tar->pos, 512) - tar->pos);
|
||||
}
|
||||
return MTAR_ESUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int mtar_finalize(mtar_t *tar) {
|
||||
/* Write two NULL records */
|
||||
return write_null_bytes(tar, sizeof(mtar_raw_header_t) * 2);
|
||||
}
|
||||
|
||||
/* Load libc.obj */
|
||||
|
||||
#ifdef MTAR_OBJ
|
||||
|
||||
#include <sys/ksys.h>
|
||||
|
||||
int mtar_init(){
|
||||
ksys_dll_t *libc = _ksys_dlopen("/sys/lib/libc.obj");
|
||||
if(!libc){
|
||||
_ksys_debug_puts("mtar.obj: libc.obj not loaded!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
_fread = _ksys_dlsym(libc, "fread");
|
||||
_fwrite = _ksys_dlsym(libc, "fwrite");
|
||||
_fclose = _ksys_dlsym(libc, "fclose");
|
||||
_fopen = _ksys_dlsym(libc, "fopen");
|
||||
_fseek = _ksys_dlsym(libc, "fseek");
|
||||
_ftell = _ksys_dlsym(libc, "ftell");
|
||||
_sprintf= _ksys_dlsym(libc, "sprintf");
|
||||
_sscanf = _ksys_dlsym(libc, "sscanf");
|
||||
_strcmp = _ksys_dlsym(libc, "strcmp");
|
||||
_strchr = _ksys_dlsym(libc, "strchr");
|
||||
_strcpy = _ksys_dlsym(libc, "strcpy");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ksys_dll_t EXPORTS[] = {
|
||||
{"mtar_init", mtar_init},
|
||||
{"mtar_open", mtar_open},
|
||||
{"mtar_close", mtar_close},
|
||||
{"mtar_seek", mtar_seek},
|
||||
{"mtar_rewind", mtar_rewind},
|
||||
{"mtar_next", mtar_next},
|
||||
{"mtar_find", mtar_find},
|
||||
{"mtar_read_header", mtar_read_header},
|
||||
{"mtar_read_data", mtar_read_data},
|
||||
{"mtar_write_header", mtar_write_header},
|
||||
{"mtar_write_file_header", mtar_write_file_header},
|
||||
{"mtar_write_dir_header", mtar_write_dir_header},
|
||||
{"mtar_write_data",mtar_write_data},
|
||||
{"mtar_finalize", mtar_finalize},
|
||||
{"mtar_strerror", mtar_strerror},
|
||||
NULL
|
||||
};
|
||||
|
||||
#endif
|
||||
91
programs/develop/libraries/microtar/microtar.h
Normal file
91
programs/develop/libraries/microtar/microtar.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Copyright (c) 2017 rxi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the MIT license. See `microtar.c` for details.
|
||||
*/
|
||||
|
||||
#ifndef MICROTAR_H
|
||||
#define MICROTAR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MTAR_VERSION "0.1.0"
|
||||
|
||||
enum {
|
||||
MTAR_ESUCCESS = 0,
|
||||
MTAR_EFAILURE = -1,
|
||||
MTAR_EOPENFAIL = -2,
|
||||
MTAR_EREADFAIL = -3,
|
||||
MTAR_EWRITEFAIL = -4,
|
||||
MTAR_ESEEKFAIL = -5,
|
||||
MTAR_EBADCHKSUM = -6,
|
||||
MTAR_ENULLRECORD = -7,
|
||||
MTAR_ENOTFOUND = -8
|
||||
};
|
||||
|
||||
enum {
|
||||
MTAR_TREG = '0',
|
||||
MTAR_TLNK = '1',
|
||||
MTAR_TSYM = '2',
|
||||
MTAR_TCHR = '3',
|
||||
MTAR_TBLK = '4',
|
||||
MTAR_TDIR = '5',
|
||||
MTAR_TFIFO = '6'
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned mode;
|
||||
unsigned owner;
|
||||
unsigned size;
|
||||
unsigned mtime;
|
||||
unsigned type;
|
||||
char name[100];
|
||||
char linkname[100];
|
||||
} mtar_header_t;
|
||||
|
||||
|
||||
typedef struct mtar_t mtar_t;
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct mtar_t {
|
||||
int (*read)(mtar_t *tar, void *data, unsigned size);
|
||||
int (*write)(mtar_t *tar, const void *data, unsigned size);
|
||||
int (*seek)(mtar_t *tar, unsigned pos);
|
||||
int (*close)(mtar_t *tar);
|
||||
void *stream;
|
||||
unsigned pos;
|
||||
unsigned remaining_data;
|
||||
unsigned last_header;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
const char* mtar_strerror(int err);
|
||||
|
||||
int mtar_open(mtar_t *tar, const char *filename, const char *mode);
|
||||
int mtar_close(mtar_t *tar);
|
||||
|
||||
int mtar_seek(mtar_t *tar, unsigned pos);
|
||||
int mtar_rewind(mtar_t *tar);
|
||||
int mtar_next(mtar_t *tar);
|
||||
int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h);
|
||||
int mtar_read_header(mtar_t *tar, mtar_header_t *h);
|
||||
int mtar_read_data(mtar_t *tar, void *ptr, unsigned size);
|
||||
|
||||
int mtar_write_header(mtar_t *tar, const mtar_header_t *h);
|
||||
int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size);
|
||||
int mtar_write_dir_header(mtar_t *tar, const char *name);
|
||||
int mtar_write_data(mtar_t *tar, const void *data, unsigned size);
|
||||
int mtar_finalize(mtar_t *tar);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
38
programs/develop/libraries/microtar/mtar.inc
Normal file
38
programs/develop/libraries/microtar/mtar.inc
Normal file
@@ -0,0 +1,38 @@
|
||||
MTAR_ESUCCESS = 0
|
||||
MTAR_EFAILURE = -1
|
||||
MTAR_EOPENFAIL = -2
|
||||
MTAR_EREADFAIL = -3
|
||||
MTAR_EWRITEFAIL = -4
|
||||
MTAR_ESEEKFAIL = -5
|
||||
MTAR_EBADCHKSUM = -6
|
||||
MTAR_ENULLRECORD = -7
|
||||
MTAR_ENOTFOUND = -8
|
||||
|
||||
MTAR_TREG = '0'
|
||||
MTAR_TLNK = '1'
|
||||
MTAR_TSYM = '2'
|
||||
MTAR_TCHR = '3'
|
||||
MTAR_TBLK = '4'
|
||||
MTAR_TDIR = '5'
|
||||
MTAR_TFIFO = '6'
|
||||
|
||||
struct mtar_header_t
|
||||
mode dd ?
|
||||
owner dd ?
|
||||
size dd ?
|
||||
mtime dd ?
|
||||
type dd ?
|
||||
name rb 100
|
||||
linkname rb 100
|
||||
ends
|
||||
|
||||
struct mtar_t
|
||||
read_func dd ?
|
||||
write_func dd ?
|
||||
seek_func dd ?
|
||||
close_func dd ?
|
||||
stream dd ?
|
||||
pos dd ?
|
||||
remaining_data dd ?
|
||||
last_header dd ?
|
||||
ends
|
||||
@@ -1,5 +1,7 @@
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
|
||||
tup.include(HELPERDIR .. "/use_fasm.lua")
|
||||
tup.rule("keymap.asm", FASM .. " %f %o", "piano.map")
|
||||
tup.rule("piano.asm", FASM .. " -dlang=" .. tup.getconfig("LANG") .. " %f %o" .. tup.getconfig("KPACK_CMD"), "%B")
|
||||
add_include(tup.getvariantdir())
|
||||
|
||||
tup.rule("echo lang fix " .. ((tup.getconfig("LANG") == "") and "en_US" or tup.getconfig("LANG")) .. " > %o", {"lang.inc"})
|
||||
tup.rule({"piano.asm", extra_inputs = {"lang.inc"}}, FASM .. " %f %o " .. tup.getconfig("KPACK_CMD"), "piano")
|
||||
|
||||
4
programs/media/piano/build.bat
Normal file
4
programs/media/piano/build.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
@echo lang fix en_US >lang.inc
|
||||
@fasm piano.asm piano
|
||||
@erase lang.inc
|
||||
@pause
|
||||
@@ -1,76 +0,0 @@
|
||||
; SPDX-License-Identifier: GPL-2.0-only
|
||||
;
|
||||
; Piano - Default Keymap (256 bytes)
|
||||
; Copyright (C) 2025 KolibriOS team
|
||||
|
||||
; ====================================================================
|
||||
|
||||
format binary as ""
|
||||
org 0
|
||||
|
||||
; ====================================================================
|
||||
|
||||
BAD_NOTE = 0xFF
|
||||
|
||||
; ====================================================================
|
||||
|
||||
keymap:
|
||||
db BAD_NOTE ; 0x00
|
||||
db BAD_NOTE ; 0x01
|
||||
db 0x21 ; 0x02 '1' -> note 0x31
|
||||
db 0x22 ; 0x03 '2' -> note 0x32
|
||||
db 0x23 ; 0x04 '3' -> note 0x33
|
||||
db 0x24 ; 0x05 '4' -> note 0x34
|
||||
db 0x25 ; 0x06 '5' -> note 0x35
|
||||
db 0x26 ; 0x07 '6' -> note 0x36
|
||||
db 0x27 ; 0x08 '7' -> note 0x37
|
||||
db 0x28 ; 0x09 '8' -> note 0x38
|
||||
db 0x29 ; 0x0A '9' -> note 0x39
|
||||
db 0x2A ; 0x0B '0' -> note 0x3A
|
||||
db 0x2B ; 0x0C '-' -> note 0x3B
|
||||
db 0x2C ; 0x0D '=' -> note 0x3C
|
||||
db 0x1C ; 0x0E Backspace -> note 0x2C
|
||||
db BAD_NOTE ; 0x0F
|
||||
|
||||
db 0x31 ; 0x10 'q' -> note 0x41
|
||||
db 0x32 ; 0x11 'w' -> note 0x42
|
||||
db 0x33 ; 0x12 'e' -> note 0x43
|
||||
db 0x34 ; 0x13 'r' -> note 0x44
|
||||
db 0x35 ; 0x14 't' -> note 0x45
|
||||
db 0x36 ; 0x15 'y' -> note 0x46
|
||||
db 0x37 ; 0x16 'u' -> note 0x47
|
||||
db 0x38 ; 0x17 'i' -> note 0x48
|
||||
db 0x39 ; 0x18 'o' -> note 0x49
|
||||
db 0x3A ; 0x19 'p' -> note 0x4A
|
||||
db 0x3B ; 0x1A '[' -> note 0x4B
|
||||
db 0x3C ; 0x1B ']' -> note 0x4C
|
||||
db 0x0C ; 0x1C Enter -> note 0x1C
|
||||
db BAD_NOTE ; 0x1D
|
||||
|
||||
db 0x01 ; 0x1E 'a' -> note 0x11
|
||||
db 0x02 ; 0x1F 's' -> note 0x12
|
||||
db 0x03 ; 0x20 'd' -> note 0x13
|
||||
db 0x04 ; 0x21 'f' -> note 0x14
|
||||
db 0x05 ; 0x22 'g' -> note 0x15
|
||||
db 0x06 ; 0x23 'h' -> note 0x16
|
||||
db 0x07 ; 0x24 'j' -> note 0x17
|
||||
db 0x08 ; 0x25 'k' -> note 0x18
|
||||
db 0x09 ; 0x26 'l' -> note 0x19
|
||||
db 0x0A ; 0x27 ';' -> note 0x1A
|
||||
db 0x0B ; 0x28 ''' -> note 0x1B
|
||||
db BAD_NOTE ; 0x29
|
||||
db BAD_NOTE ; 0x2A
|
||||
|
||||
db 0x1B ; 0x2B '\' -> note 0x2B
|
||||
db 0x11 ; 0x2C 'z' -> note 0x21
|
||||
db 0x12 ; 0x2D 'x' -> note 0x22
|
||||
db 0x13 ; 0x2E 'c' -> note 0x23
|
||||
db 0x14 ; 0x2F 'v' -> note 0x24
|
||||
db 0x15 ; 0x30 'b' -> note 0x25
|
||||
db 0x16 ; 0x31 'n' -> note 0x26
|
||||
db 0x17 ; 0x32 'm' -> note 0x27
|
||||
db 0x18 ; 0x33 ',' -> note 0x28
|
||||
db 0x19 ; 0x34 '.' -> note 0x29
|
||||
db 0x1A ; 0x35 '/' -> note 0x2A
|
||||
|
||||
times 256-($-keymap) db BAD_NOTE
|
||||
File diff suppressed because it is too large
Load Diff
@@ -86,7 +86,7 @@ commands: ; all commands must be in uppercase
|
||||
dd 'CWD', login_first, login_first, login_first, cmdCWD
|
||||
dd 'XCWD', login_first, login_first, login_first, cmdCWD
|
||||
dd 'DELE', login_first, login_first, login_first, cmdDELE
|
||||
dd 'HELP', login_first, login_first, login_first, cmdHELP
|
||||
; dd 'HELP', login_first, login_first, login_first, cmd_HELP
|
||||
dd 'LIST', login_first, login_first, login_first, cmdLIST
|
||||
; dd 'MDTM', login_first, login_first, login_first, cmd_MDTM
|
||||
; dd 'MKD', login_first, login_first, login_first, cmd_MKD
|
||||
@@ -1247,68 +1247,6 @@ cmdTYPE:
|
||||
sendFTP "200 Command ok"
|
||||
ret
|
||||
|
||||
;------------------------------------------------
|
||||
; "HELP"
|
||||
;
|
||||
; Provide help information.
|
||||
;
|
||||
;------------------------------------------------
|
||||
align 4
|
||||
cmdHELP:
|
||||
|
||||
lea edi, [ebp + thread_data.buffer]
|
||||
mov eax, '214 '
|
||||
stosd
|
||||
mov eax, 'Help'
|
||||
stosd
|
||||
mov ax, ': '
|
||||
stosw
|
||||
|
||||
mov esi, commands ; pointer to commands table
|
||||
|
||||
.next_command:
|
||||
cmp byte [esi], 0 ; end of table?
|
||||
je .list_done
|
||||
|
||||
; Copy command name (4 bytes), skip null bytes
|
||||
mov ecx, 4
|
||||
.copy_name:
|
||||
mov al, [esi]
|
||||
test al, al
|
||||
jz .skip_null
|
||||
stosb
|
||||
.skip_null:
|
||||
inc esi
|
||||
loop .copy_name
|
||||
|
||||
; Add space after command name
|
||||
mov al, ' '
|
||||
stosb
|
||||
|
||||
; Skip the four address pointers (16 bytes)
|
||||
add esi, 16
|
||||
jmp .next_command
|
||||
|
||||
.list_done:
|
||||
; Remove trailing space (if any)
|
||||
dec edi
|
||||
; Add CRLF
|
||||
mov ax, 0x0a0d ; \r\n
|
||||
stosw
|
||||
xor al, al ; null terminator
|
||||
stosb
|
||||
|
||||
; Calculate length
|
||||
lea edx, [ebp + thread_data.buffer]
|
||||
sub edi, edx
|
||||
|
||||
; Send response
|
||||
mcall send, [ebp + thread_data.socketnum], edx, edi
|
||||
; Also log to console
|
||||
invoke con_write_asciiz, edx
|
||||
|
||||
ret
|
||||
|
||||
;------------------------------------------------
|
||||
; "USER"
|
||||
;
|
||||
|
||||
16
programs/other/GameHack/Makefile
Executable file
16
programs/other/GameHack/Makefile
Executable file
@@ -0,0 +1,16 @@
|
||||
KTCC_DIR=../../develop/ktcc/trunk
|
||||
|
||||
NAME=gamehack
|
||||
|
||||
KTCC=$(KTCC_DIR)/bin/kos32-tcc
|
||||
KPACK=kpack
|
||||
|
||||
SRC=gh_shell.c
|
||||
CFLAGS=-I $(KTCC_DIR)/libc/include
|
||||
LIBS = -lck
|
||||
|
||||
all:
|
||||
$(KTCC) $(CFLAGS) $(SRC) $(LIBS) -o $(NAME)
|
||||
$(KPACK) $(NAME)
|
||||
clean:
|
||||
rm $(NAME)
|
||||
72
programs/other/GameHack/gh_core.c
Normal file
72
programs/other/GameHack/gh_core.c
Normal file
@@ -0,0 +1,72 @@
|
||||
int PID=-1;
|
||||
|
||||
int kdebugger_write(unsigned ID, unsigned n, unsigned addr, unsigned* buff)
|
||||
{
|
||||
int num;
|
||||
__asm__ __volatile__(
|
||||
"int $0x40"
|
||||
:"=a"(num)
|
||||
:"a"(69), "b"(7), "c"(ID), "d"(n),"S"(addr),"D"(buff)
|
||||
);
|
||||
return num;
|
||||
}
|
||||
|
||||
int kdebugger_read(unsigned ID, unsigned n, unsigned addr, unsigned* buff)
|
||||
{
|
||||
int num;
|
||||
__asm__ __volatile__(
|
||||
"int $0x40"
|
||||
:"=a"(num)
|
||||
:"a"(69), "b"(6), "c"(ID), "d"(n),"S"(addr),"D"(buff)
|
||||
);
|
||||
return num;
|
||||
}
|
||||
|
||||
void kdebugger_pause(unsigned ID)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"int $0x40"
|
||||
::"a"(69), "b"(4), "c"(ID)
|
||||
);
|
||||
}
|
||||
|
||||
void kdebugger_play(unsigned ID)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"int $0x40"
|
||||
::"a"(69), "b"(5), "c"(ID)
|
||||
);
|
||||
}
|
||||
|
||||
void kdebugger_disconnect(unsigned ID)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"int $0x40"
|
||||
::"a"(69), "b"(3), "c"(ID)
|
||||
);
|
||||
}
|
||||
|
||||
int load_game(char *app_name, char *args)
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct file_op_t
|
||||
{
|
||||
unsigned fn;
|
||||
unsigned flags;
|
||||
char* args;
|
||||
unsigned res1, res2;
|
||||
char zero;
|
||||
char* app_name __attribute__((packed));
|
||||
} file_op;
|
||||
#pragma pack(pop)
|
||||
|
||||
memset(&file_op, 0, sizeof(file_op));
|
||||
file_op.fn = 7;
|
||||
file_op.flags = 1;
|
||||
file_op.args = args;
|
||||
file_op.app_name = app_name;
|
||||
|
||||
register int val;
|
||||
asm volatile ("int $0x40":"=a"(val):"a"(70), "b"(&file_op));
|
||||
return val;
|
||||
}
|
||||
96
programs/other/GameHack/gh_shell.c
Normal file
96
programs/other/GameHack/gh_shell.c
Normal file
@@ -0,0 +1,96 @@
|
||||
#include <conio.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <kos32sys1.h>
|
||||
#include "gh_core.c"
|
||||
|
||||
#define CMD_LEN 255
|
||||
#define TITLE "GameHack 1.0 ALPHA "
|
||||
|
||||
char cmd_line[CMD_LEN];
|
||||
char cmd_line_tmp[CMD_LEN];
|
||||
|
||||
void notify_show(char *text)
|
||||
{
|
||||
start_app("/sys/@notify", text);
|
||||
}
|
||||
|
||||
void cmd_processing()
|
||||
{
|
||||
strcpy(cmd_line_tmp, cmd_line);
|
||||
char *cmd = strtok(cmd_line_tmp, " \n");
|
||||
if(!strcmp(cmd, "pause")){
|
||||
kdebugger_pause(PID);
|
||||
}
|
||||
else if(!strcmp(cmd, "play")){
|
||||
kdebugger_play(PID);
|
||||
}
|
||||
else if(!strcmp(cmd, "exit")){
|
||||
exit(0);
|
||||
}
|
||||
else if(!strcmp(cmd, "write")){
|
||||
unsigned addr=0;
|
||||
int val =0;
|
||||
if(sscanf(cmd_line, "%s %x %d %d",cmd_line, &addr, &val, &val)==3){
|
||||
if(kdebugger_write(PID, sizeof(int), addr, &val)==-1){
|
||||
puts("Memory write error!");
|
||||
}
|
||||
}else{
|
||||
puts("Invalid arguments!");
|
||||
}
|
||||
}
|
||||
else if(!strcmp(cmd, "read")){
|
||||
unsigned addr=0;
|
||||
int val =0;
|
||||
if(sscanf(cmd_line, "%s %x %x",cmd_line, &addr, &addr)==2){
|
||||
if(kdebugger_read(PID, sizeof(int), addr, &val)==-1){
|
||||
puts("Memory read error!");
|
||||
}
|
||||
printf("0x%.8X: %d\n", addr, val);
|
||||
}else{
|
||||
puts("Invalid arguments!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if(!strcmp(cmd, "help"))
|
||||
{
|
||||
puts("Commands:");
|
||||
puts(" write [addres] [value] - Write DWORD value by address.");
|
||||
puts(" read [addres] [value] - Read DWORD value by address.");
|
||||
puts(" pause - Suspend the game (process)." );
|
||||
puts(" play - Resume running the game(process).");
|
||||
puts(" find [value] - Search for DWORD value in memory(VIP).");
|
||||
}
|
||||
else if(!strcmp(cmd, "find"))
|
||||
{
|
||||
puts("Not yet implemented ...");
|
||||
}
|
||||
else if(cmd != NULL){
|
||||
puts("Unknown command!");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc!=2 ){
|
||||
notify_show("'No game selected!' -E");
|
||||
exit(0);
|
||||
}
|
||||
con_init_console_dll();
|
||||
con_set_title(TITLE);
|
||||
PID = load_game(argv[1], NULL);
|
||||
PID = 2;
|
||||
if(PID<0){
|
||||
notify_show("'Game not loaded!' -E");
|
||||
exit(0);
|
||||
}
|
||||
kdebugger_play(PID);
|
||||
while (1){
|
||||
printf("GameHack> ");
|
||||
con_gets(cmd_line, CMD_LEN);
|
||||
cmd_processing();
|
||||
memset(cmd_line, '\n', CMD_LEN);
|
||||
}
|
||||
}
|
||||
18
programs/other/TEAtool/Makefile
Executable file
18
programs/other/TEAtool/Makefile
Executable file
@@ -0,0 +1,18 @@
|
||||
KTCC_DIR=../../develop/ktcc/trunk
|
||||
|
||||
NAME=teatool
|
||||
|
||||
KTCC=$(KTCC_DIR)/bin/kos32-tcc
|
||||
KPACK=kpack
|
||||
|
||||
SRC=teatool.c
|
||||
CFLAGS=-nostdinc -I $(KTCC_DIR)/libc/include
|
||||
LFLAGS=-nostdlib -L $(KTCC_DIR)/bin/lib $(KTCC_DIR)/bin/lib/start.o
|
||||
LIBS = -lck
|
||||
|
||||
all:
|
||||
$(KTCC) $(CFLAGS) $(LFLAGS) $(SRC) $(LIBS) -o $(NAME)
|
||||
$(KPACK) $(NAME)
|
||||
|
||||
clean:
|
||||
rm $(NAME)
|
||||
49
programs/other/TEAtool/lang_en.c
Normal file
49
programs/other/TEAtool/lang_en.c
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <stdio.h>
|
||||
#define INVALID_ARG "Invalid arguments! Use the help: -h!\n"
|
||||
#define KEY_RECORD_IN_FILE "The key is recorded in file: %s\n"
|
||||
#define INCORRECT_FILE "Error! Incorrect file:'%s'\n"
|
||||
#define NO_KEY_OR_KEYFILE "No key or key file!\n"
|
||||
#define INVALID_KEY_FORMAT "Invalid key format!\n"
|
||||
#define FILE_NOT_FOUND "File '%s' not found!\n"
|
||||
#define DATA_DECRYPT "Data from file: %s successfully DECRYPTED to file: %s\n"
|
||||
#define DATA_ENCRYPT "Data from file: %s successfully ENCRYPTED to file: %s\n"
|
||||
#define FILE_DECRYPTION "File decryption...\n"
|
||||
#define FILE_ENCRYPTION "File encryption...\n"
|
||||
#define RECORD_DECRYPT_DATA "Record decryped data...\n"
|
||||
#define LOAD_IN_RAM "Loading a '%s' file in RAM...\n"
|
||||
#define RECORD_ENCRYPT_DATA "Record encryped data...\n"
|
||||
#define MEMORY_ERROR "To big file, not enough memory! Use normal mode."
|
||||
|
||||
void show_help()
|
||||
{
|
||||
puts("Usage: \nTEAtool [infile] [outfile] [arguments]\n");
|
||||
puts("Arguments:");
|
||||
puts("-e [mode] Encrypt file in 'speed' or 'normal' mode.");
|
||||
puts("-d [mode] Decrypt file in 'speed' or 'normal' mode.");
|
||||
puts(" In 'speed' mode, file is entirely loaded into RAM.");
|
||||
puts(" In 'normal' mode, file is loaded with parts in RAM.");
|
||||
puts("-k [key] 128bit-key in hex format.");
|
||||
puts("-K [keyfile] Use key from file.");
|
||||
puts("-r [key] [keyfile].key Key entry to key file.");
|
||||
puts("-h This reference");
|
||||
puts("-a About the program \n");
|
||||
}
|
||||
|
||||
void show_about()
|
||||
{
|
||||
puts("\n");
|
||||
puts("-----------TEAtool-ENG-----------\n");
|
||||
printf(" ) ( Version: \n");
|
||||
printf(" ( ) ) 1.8-stable \n");
|
||||
printf(" ) ( ( \n");
|
||||
printf(" _______)_ Author: \n");
|
||||
printf(" .-'---------| turbocat2001 \n");
|
||||
printf("( C|/////////| \n");
|
||||
printf(" '-./////////| Tester: rgimad \n");
|
||||
printf(" '_________' \n");
|
||||
printf(" '-------'' License: GPLv3 \n\n");
|
||||
printf(" Powered by: \n");
|
||||
printf(" Tiny Encryption Algorithm. \n\n");
|
||||
}
|
||||
|
||||
|
||||
9
programs/other/TEAtool/readme.txt
Normal file
9
programs/other/TEAtool/readme.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Encrypting the "in.file" file with the "FFAB1100C176001F1ADDB8E792001EA5" key in normal mode:
|
||||
# teatool in.file out.file -k FFAB1100C176001F1ADDB8E792001EA5 -e normal
|
||||
Encrypting the "in.file" file with the key-file "my.key" in speed mode:*
|
||||
# teatool in.file out.file -K my.key -e speed
|
||||
Writing the "FFAB1100C176001F1ADDB8E792001EA5" key to the key-file "my.key"*
|
||||
# teatool -r FFAB1100C176001F1ADDB8E792001EA5 my
|
||||
|
||||
|
||||
|
||||
62
programs/other/TEAtool/tea.c
Normal file
62
programs/other/TEAtool/tea.c
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void TEA_encrypt (uint32_t block[2], uint32_t key[4])
|
||||
{
|
||||
/* set up */
|
||||
uint32_t v0 = block[0];
|
||||
uint32_t v1 = block[1];
|
||||
uint32_t sum = 0;
|
||||
uint32_t i;
|
||||
|
||||
/* a key schedule constant */
|
||||
uint32_t delta = 0x9e3779b9;
|
||||
|
||||
/* cache key */
|
||||
uint32_t k0 = key[0];
|
||||
uint32_t k1 = key[1];
|
||||
uint32_t k2 = key[2];
|
||||
uint32_t k3 = key[3];
|
||||
|
||||
/* basic cycle start */
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
sum += delta;
|
||||
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
|
||||
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
|
||||
}
|
||||
/* end cycle */
|
||||
|
||||
block[0] = v0;
|
||||
block[1] = v1;
|
||||
}
|
||||
|
||||
void TEA_decrypt (uint32_t* block, uint32_t* key)
|
||||
{
|
||||
/* set up */
|
||||
uint32_t v0 = block[0];
|
||||
uint32_t v1 = block[1];
|
||||
uint32_t sum = 0xC6EF3720;
|
||||
uint32_t i;
|
||||
|
||||
/* a key schedule constant */
|
||||
uint32_t delta = 0x9e3779b9;
|
||||
|
||||
/* cache key */
|
||||
uint32_t k0 = key[0];
|
||||
uint32_t k1 = key[1];
|
||||
uint32_t k2 = key[2];
|
||||
uint32_t k3 = key[3];
|
||||
|
||||
/* basic cycle start */
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
|
||||
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
|
||||
sum -= delta;
|
||||
}
|
||||
/* end cycle */
|
||||
|
||||
block[0] = v0;
|
||||
block[1] = v1;
|
||||
}
|
||||
303
programs/other/TEAtool/teatool.c
Executable file
303
programs/other/TEAtool/teatool.c
Executable file
@@ -0,0 +1,303 @@
|
||||
/* Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv2 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <conio.h>
|
||||
|
||||
#include "lang_en.c"
|
||||
#include "tea.c"
|
||||
|
||||
#define ENCRYPT 1
|
||||
#define DECRYPT 2
|
||||
|
||||
typedef unsigned char flag;
|
||||
uint32_t key[4];
|
||||
|
||||
long size_orig_file(FILE* file)
|
||||
{
|
||||
fseek(file, 0, SEEK_END);
|
||||
long size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
|
||||
long size_xcrypt_file(FILE* file)
|
||||
{
|
||||
fseek(file, 0, SEEK_END);
|
||||
long size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
if(size%8==0) {
|
||||
return size;
|
||||
}else{
|
||||
return (size/8+1)*8;
|
||||
}
|
||||
}
|
||||
|
||||
void xcrypt_file_speed(char *in_file, char* out_file, char arg)
|
||||
{
|
||||
FILE *input, *output;
|
||||
|
||||
if((input = fopen(in_file,"rb"))==NULL){
|
||||
printf(FILE_NOT_FOUND, in_file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
output = fopen(out_file,"wb");
|
||||
|
||||
long size_f=size_xcrypt_file(input);
|
||||
uint8_t size_diff;
|
||||
size_diff=(uint8_t)(size_f-size_orig_file(input));
|
||||
uint32_t *buff;
|
||||
buff=malloc(size_f);
|
||||
if(!buff) {
|
||||
puts(MEMORY_ERROR);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if(arg==ENCRYPT){
|
||||
printf(LOAD_IN_RAM,in_file);
|
||||
fread(buff, 1,size_f, input);
|
||||
printf(FILE_ENCRYPTION);
|
||||
|
||||
for(long i=0; i<(size_f/4); i=i+2)
|
||||
{
|
||||
TEA_encrypt(buff+i,key);
|
||||
}
|
||||
|
||||
printf(RECORD_ENCRYPT_DATA);
|
||||
fwrite(&size_diff,1, 1, output);
|
||||
fwrite(buff,1,size_f, output);
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
printf(DATA_ENCRYPT,in_file,out_file);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
else if(arg==DECRYPT){
|
||||
long size_f=size_orig_file(input);
|
||||
printf(LOAD_IN_RAM,in_file);
|
||||
fread(&size_diff,1,1,input);
|
||||
fread(buff,1,size_f-1, input);
|
||||
printf(FILE_DECRYPTION);
|
||||
|
||||
for(long i=0; i<size_f/4; i=i+2)
|
||||
{
|
||||
TEA_decrypt(buff+i,key);
|
||||
}
|
||||
|
||||
printf(RECORD_DECRYPT_DATA);
|
||||
fwrite(buff,1,size_f-size_diff-1, output);
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
printf(DATA_DECRYPT,in_file,out_file);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void xcrypt_file(char *in_file, char* out_file, char arg)
|
||||
{
|
||||
uint32_t temp_block[2];
|
||||
FILE *input, *output;
|
||||
|
||||
if((input = fopen(in_file,"rb"))==NULL){
|
||||
printf(FILE_NOT_FOUND, in_file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
output = fopen(out_file,"wb");
|
||||
|
||||
register long size_f=size_xcrypt_file(input);
|
||||
uint8_t size_diff=(uint8_t)(size_f-size_orig_file(input));
|
||||
|
||||
if(arg==ENCRYPT){
|
||||
fwrite(&size_diff,1,1,output);
|
||||
printf(FILE_ENCRYPTION);
|
||||
|
||||
while(!feof(input))
|
||||
{
|
||||
memset(temp_block, 0x00, 2);
|
||||
fread(temp_block, sizeof(uint32_t), 2, input) ;
|
||||
TEA_encrypt(temp_block,key);
|
||||
fwrite(temp_block, sizeof(uint32_t),2, output);
|
||||
}
|
||||
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
printf(DATA_ENCRYPT,in_file,out_file);
|
||||
exit(0);
|
||||
|
||||
}
|
||||
else if(arg==DECRYPT){
|
||||
size_f = size_orig_file(input);
|
||||
fread(&size_diff,1,1,input);
|
||||
size_f=size_f-size_diff-1;
|
||||
printf(FILE_DECRYPTION);
|
||||
|
||||
while(!feof(input))
|
||||
{
|
||||
fread(temp_block, sizeof(uint32_t), 2, input);
|
||||
TEA_decrypt(temp_block,key);
|
||||
|
||||
if(size_f>=8){
|
||||
fwrite(temp_block,sizeof(uint32_t),2,output);
|
||||
}else{
|
||||
fwrite(temp_block,1,size_f,output);
|
||||
}
|
||||
|
||||
size_f=size_f-8;
|
||||
|
||||
if(size_f<0){
|
||||
size_f=0;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
printf(DATA_DECRYPT,in_file,out_file);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void str_to_strkey(char *str, char str_key[4][9])
|
||||
{
|
||||
int count=0;
|
||||
for(int i=0; i<4; i++)
|
||||
{
|
||||
int j=0;
|
||||
while (j<8)
|
||||
{
|
||||
str_key[i][j]=str[count];
|
||||
count++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int valid_key(char *str)
|
||||
{
|
||||
int count=0;
|
||||
char hex[]={"abcdefABCDEF0123456789"};
|
||||
for(int i=0; i<32; i++)
|
||||
{
|
||||
if(strchr(hex,str[i])!=NULL){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if(count==32){return 1;}
|
||||
else{ return 0;}
|
||||
}
|
||||
|
||||
|
||||
void key_con_read(char *str)
|
||||
{
|
||||
char str_key[4][9];
|
||||
if(valid_key(str)&&(strlen(str)==32))
|
||||
{
|
||||
for(int i=0; i<4; i++){
|
||||
str_to_strkey(str, str_key);
|
||||
key[i]=(uint32_t)strtol(str_key[i],NULL,16);
|
||||
}
|
||||
}else{
|
||||
printf(INVALID_KEY_FORMAT);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void key_file_read(char *key_file)
|
||||
{
|
||||
FILE *keyfile;
|
||||
if((keyfile = fopen(key_file,"rb"))==NULL){
|
||||
printf(FILE_NOT_FOUND, key_file);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if(size_orig_file(keyfile)==16) {
|
||||
fread(key,sizeof(uint32_t),4, keyfile);
|
||||
}else{
|
||||
printf(INVALID_KEY_FORMAT);
|
||||
exit(-1);
|
||||
}
|
||||
fclose(keyfile);
|
||||
}
|
||||
|
||||
|
||||
void findopt(int argc, char *argv[],char *in_file, char *out_file)
|
||||
{
|
||||
char found=0;
|
||||
for(int j=3; j<argc; j++)
|
||||
{
|
||||
if(!strcmp(argv[j],"-k")){
|
||||
found=1;
|
||||
key_con_read(argv[j+1]);
|
||||
break;
|
||||
}
|
||||
else if(!strcmp(argv[j],"-K")){
|
||||
found=1;
|
||||
key_file_read(argv[j+1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found){
|
||||
printf(NO_KEY_OR_KEYFILE);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for(int i=3;i<argc; i++){
|
||||
if(!strcmp(argv[i],"-e"))
|
||||
{
|
||||
if(!strcmp(argv[i+1],"normal")){xcrypt_file(in_file, out_file, ENCRYPT);}
|
||||
if(!strcmp(argv[i+1],"speed")){xcrypt_file_speed(in_file, out_file, ENCRYPT);}
|
||||
}
|
||||
if(!strcmp(argv[i],"-d"))
|
||||
{
|
||||
if(!strcmp(argv[i+1],"normal")){xcrypt_file(in_file, out_file, DECRYPT);}
|
||||
if(!strcmp(argv[i+1],"speed")){xcrypt_file_speed(in_file, out_file, DECRYPT);}
|
||||
}
|
||||
}
|
||||
printf(INVALID_ARG);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void key_write_in_file(char *keyfilename)
|
||||
{
|
||||
FILE *keyfile;
|
||||
if((keyfile = fopen(strcat(keyfilename, ".key"), "wb"))==NULL){
|
||||
printf(INCORRECT_FILE, keyfilename);
|
||||
exit(-1);
|
||||
}
|
||||
fwrite(key,sizeof(uint8_t), 16, keyfile);
|
||||
printf(KEY_RECORD_IN_FILE, keyfilename);
|
||||
fclose(keyfile);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
con_init_console_dll();
|
||||
con_set_title("TEAtool\0");
|
||||
if(argc==7){
|
||||
findopt(argc,argv, argv[1],argv[2]);
|
||||
}
|
||||
else if(argc==2 && !strcmp(argv[1],"-a")){
|
||||
show_about();
|
||||
exit(0);
|
||||
}
|
||||
else if(argc==2 && !strcmp(argv[1],"-h")){
|
||||
show_help();
|
||||
exit(0);
|
||||
}
|
||||
else if(argc==4 && !strcmp(argv[1],"-r")){
|
||||
key_con_read(argv[2]);
|
||||
key_write_in_file(argv[3]);
|
||||
}
|
||||
else{
|
||||
printf(INVALID_ARG);
|
||||
exit(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
if tup.getconfig("NO_OB07") ~= "" then return end
|
||||
if tup.getconfig("HELPERDIR") == ""
|
||||
then
|
||||
HELPERDIR = "../../"
|
||||
end
|
||||
|
||||
tup.include(HELPERDIR .. "/use_ob07.lua")
|
||||
|
||||
build_ob07({"SRC/FB2READ.ob07"}, "fb2read", "-upper");
|
||||
@@ -1,7 +1,6 @@
|
||||
OB07 = tup.getcwd() .. "/develop/oberon07/compiler"
|
||||
OB07_FLAGS = "-stk 1 -nochk a"
|
||||
|
||||
function build_ob07(input, output, extra_flags)
|
||||
extra_flags = extra_flags or ""
|
||||
tup.rule(input, OB07 .. " %f kosexe -out %o " .. OB07_FLAGS .. " " .. extra_flags .. " " .. tup.getconfig("KPACK_CMD"), output)
|
||||
end
|
||||
OB07 = tup.getcwd() .. "/develop/oberon07/compiler"
|
||||
OB07_FLAGS = "-stk 1 -nochk a"
|
||||
|
||||
function build_ob07(input, output)
|
||||
tup.rule(input, OB07 .. " %f kosexe -out %o " .. OB07_FLAGS .. " " .. tup.getconfig("KPACK_CMD"), output)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user