diff --git a/programs/network/icq/trunk/2000.inc b/programs/network/icq/trunk/2000.inc new file mode 100644 index 0000000000..7ee68a2423 --- /dev/null +++ b/programs/network/icq/trunk/2000.inc @@ -0,0 +1,160 @@ +; constants +FLAP_HEAD_SIZE = 6 +SNAC_HEAD_SIZE = 10 + +;AUTH_MESSAGE = 0008h +;USER_ADDED_MESS = 000Ch +;AUTH_REQ_MESS = 0006h +;URL_MESS = 0004h +;WEB_MESS = 000dh +;EMAIL_MESS = 000eh +;MASS_MESS_MASK = 8000h +;MRURL_MESS = 8004h +;NORM_MESS = 0001h +;MRNORM_MESS = 8001h +;CONTACT_MESS = 0013h +;MRCONTACT_MESS = 8013h +; +; +; +;CAP_PRECAP = "\x09\x46\x13" +;CAP_PRERTF = "\x97\xb1\x27" +;CAP_POSCAP = "\x4c\x7f\x11\xd1\x82\x22\x44\x45\x53\x54\x00\x00" +;CAP_POSRTF = "\x24\x3c\x43\x34\xad\x22\xd6\xab\xf7\x3f\x14\x92" + +; +;Fingerprinting Capabilities +; +;CAP_M2001 = "\x2e\x7a\x64" "\x75" "\xfa\xdf\x4d\xc8\x88\x6f\xea\x35\x95\xfd\xb6\xdf" +;CAP_M2001_2 = "\xa0\xe9\x3f" "\x37" "\x4f\xe9\xd3\x11\xbc\xd2\x00\x04\xac\x96\xdd\x96" +;CAP_M2002 = "\x10\xcf\x40" "\xd1" "\x4f\xe9\xd3\x11\xbc\xd2\x00\x04\xac\x96\xdd\x96" +;CAP_MLITE = "\x56\x3f\xc8" "\x09" "\x0b\x6f\x41\xbd\x9f\x79\x42\x26\x09\xdf\xa2\xf3" +;CAP_SIMICQ = "\x97\xb1\x27" "\x51" "\x24\x3c\x43\x34\xad\x22\xd6\xab\xf7\x3f\x14\x48" +;CAP_MICQ = "mICQ \xa9 R.K. \x00\x00\x00\x00" +;CAP_TRILL_NORM = "\x97\xb1\x27" "\x51" "\x24\x3c\x43\x34\xad\x22\xd6\xab\xf7\x3f\x14\x09" +;CAP_TRILL_CRYPT= "\xf2\xe7\xc7" "\xf4" "\xfe\xad\x4d\xfb\xb2\x35\x36\x79\x8b\xdf\x00\x00" +;CAP_LICQ = "\x09\x49\x13" + +; +;DC Packet Types +; +;PEER_INIT = 0ffh +;PEER_INITACK = 01h +;PEER_MSG = 02h +;PEER_INIT2 = 03h +;PEER_FILE_INIT = 00h +;PEER_FILE_INIT_ACK = 01h +;PEER_FILE_START = 02h +;PEER_FILE_START_ACK = 03h +;PEER_FILE_STOP = 04h +;PEER_FILE_SPEED = 05h +;PEER_FILE_DATA = 06h + + +ICQ_PORT = 5190 +; +; FLAP transport +; +FLAP_ID = 02ah + +struc FLAP_head +{ + .bId db FLAP_ID ;id byte + .bCh db ? ;channel + .wSn dw ? ;seq number + .wDs dw ? ;data size +} +; +; Channels ID +; + +NEW_CONNECTION = 01h +SNAC_DATA = 02h +FLAP_ERROR = 03h +CLOSE_CONNECTION = 04h +KEEP_ALIVE = 05h + +; +; SNAC +; +struc SNAC_head +{ + .wFid dw ?; Family id + .wSid dw ?; subtype id + .wDf dw ?; SNAC flags + .dRi dd ?; SNAC Request id +} + +; +; +; Familes/SNACs list +; + +GENERIC_SN = 0001h +LOCATION_SN = 0002h +BUDDY_LIST_SN = 0003h +ICBM_SN = 0004h +PRIVACY_SN = 0009h +BUDDY_ICONS_SN = 0010h +SSI_SN = 0013h +AUTH_REG_SN = 0017h + +; +; TLV +; +struc TLV_head +{ + .wTn dw ?; TLV type number + .wLv dw ?; TLV length value +} + +; +; userinfo block +; +struc UI_head +{ + .bUinLength db 0 ; UIN/screenname length + .bUin db 11 dup 0 ; string + .wWl dw 0 ; Warning level + .dUserClass dd 0 + .dCreateTime dd 0 + .dSignonTime dd 0 + .wIdleTime dw 0 + .dCreationTime dd 0 + .dUserStatus dd 0 + .dIpAddress dd 0 + .dOnlineTime dd 0 + +} + +; +;Roasting array +; +ROASTING_ARRAY db 0F3h, 026h, 081h, 0C4h, 039h, 086h, 0DBh, 092h, 071h, 0A3h, 0B9h, 0E6h, 053h, 07Ah, 095h, 07Ch + +; +; Status flags +; +; + + STATUS_WEBAWARE = 0x0001 ;Status webaware flag + STATUS_SHOWIP = 0x0002 ;Status show ip flag + STATUS_BIRTHDAY = 0x0008 ;User birthday flag + STATUS_WEBFRONT = 0x0020 ;User active webfront flag + STATUS_DCDISABLED = 0x0100 ;Direct connection not supported + STATUS_DCAUTH = 0x1000 ;Direct connection upon authorization + STATUS_DCCONT = 0x2000 ;DC only with contact users + +; +; Status +; + + STATUS_ONLINE = 0x0000 ;Status is online + STATUS_AWAY = 0x0001 ;Status is away + STATUS_DND = 0x0002 ;Status is no not disturb (DND) + STATUS_NA = 0x0004 ;Status is not available (N/A) + STATUS_OCCUPIED = 0x0010 ;Status is occupied (BISY) + STATUS_FREE4CHAT = 0x0020 ;Status is free for chat + STATUS_INVISIBLE = 0x0100 ;Status is invisible + + diff --git a/programs/network/icq/trunk/EDITBOX.INC b/programs/network/icq/trunk/EDITBOX.INC new file mode 100644 index 0000000000..72be561e47 --- /dev/null +++ b/programs/network/icq/trunk/EDITBOX.INC @@ -0,0 +1,275 @@ +; SEE YOU File FAQ.txt and HISTORY. Good Like! +;;;;;;;;;;;;;;;;;; +include 'editbox.mac' ;макрос который должен облегчить жизнь :) специально для editbox +;;;;;;;;;;;;;;;;;; +macro use_edit_box procinfo,scr_h,scr_w +{ +edit_box: +ed_width equ [edi] ;ширина компонента +ed_left equ [edi+4] ;положение по оси х +ed_top equ [edi+8] ;положение по оси у +ed_color equ [edi+12] ;цвет фона компонента +shift_color equ [edi+16] ;=0x6a9480 +ed_focus_border_color equ [edi+20] ;цвет рамки компонента +ed_blur_border_color equ [edi+24] ;цвет не активного компонента +ed_text_color equ [edi+28] ;цвет текста +ed_max equ [edi+32] ;кол-во символов которые можно максимально ввести +ed_text equ [edi+36] ;указатель на буфер +ed_flags equ [edi+40] ;флаги +ed_size equ [edi+42] ;кол-во символов +ed_pos equ [edi+46] ;позиция курсора +ed_offset equ [edi+50] ;смещение +cl_curs_x equ [edi+54] ;предыдущее координата курсора по х +cl_curs_y equ [edi+58] ;предыдущее координата курсора по у +ed_shift_pos equ [edi+62] ;положение курсора +ed_shift_pos_old equ [edi+66] ;старое положение курсора +;========================================================== +;=== процедура прорисовки ================================= +;========================================================== +.draw: +pusha +;--- рисуем рамку --- + call .draw_border ; Функция стабильна +.draw_bg_cursor_text: +;--- изменяем смещение, если надо --- + call .check_offset ;вычисление позиции курсора стабильна +;--- рисуем внутреннюю область --- + call .draw_bg ;нарисовать прямоугольник рабочей области +;---- рисуем выделение, по shift если есть + call .draw_shift +.draw_cursor_text: +;--- рисуем курсор --- + ;--- может его не надо рисовать ---- + test word ed_flags,ed_focus + je @f + call .draw_cursor +@@: + call .draw_text +;;;;;;;;;;;;;;;;;;;;;;;;;; +;Общий выход из editbox для всех функций и пост обработчиков +;;;;;;;;;;;;;;;;;;;;;;;;;; +.editbox_exit: +edit_ex +;========================================================== +;=== обработка клавиатуры ================================= +;========================================================== +.key: +pusha + test word ed_flags,ed_focus ; если не в фокусе, выходим + je .editbox_exit +;Проверка нажат shift ? + call .check_shift +;---------------------------------------------------------- +;--- проверяем, что нажато -------------------------------- +;---------------------------------------------------------- +use_key_process backspase,delete,left,right,home,end,insert +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Заглушка на обработку клавиш вверх и вниз т.е. при обнаружении этих кодов происходит выход из обработчика +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +use_key_no_process up,down,esc +;--- нажата другая клавиша --- +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Проверка установлен ли флаг при котором нужно выводить только цифры в нужном боксе если такойнеобходимости нет нужно закоментировать макрос +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +use_key_figures_only +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;проверка на shift был ли нажат +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +are_key_shift_press +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; проверяем, находится ли курсор в конце + дальнейшая обработка +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +are_key_cur_end +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Обработка клавиш insert,delete.backspase,home,end,left,right +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +use_work_key +;========================================================== +;=== обработка мыши ======================================= +;========================================================== +.mouse: +pusha +;debug +;---------------------------------------------------------- +;--- получаем состояние кнопок мыши ----------------------- +;---------------------------------------------------------- + mcall 37,2 +;---------------------------------------------------------- +;--- проверяем состояние ---------------------------------- +;---------------------------------------------------------- + test eax,1 + jnz .mouse_left_button + and word ed_flags,ed_mouse_on_off + xor ebx,ebx + mov dword [mouse_flag],ebx + jmp .editbox_exit +.mouse_left_button: +;---------------------------------------------------------- +;--- блокировка от фокусировки в других боксах при попадании на них курсора +;---------------------------------------------------------- + mov eax,dword [mouse_flag] + test eax,eax + jz @f + cmp eax,edi + je @f + jmp ._blur +;---------------------------------------------------------- +;--- получаем координаты мыши относительно 0 т.е всей области экрана +;---------------------------------------------------------- +@@: mcall 37,0 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Функция обработки мышки получение координат и проверка их + выделения +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +use_work_mause scr_h,scr_w +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Общие функции обработки +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +use_general_func +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Функции для работы с key +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +use_key_func +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Функции для работы с mouse +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +use_mouse_func scr_w +} +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Bit mask from editbox +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ed_figure_only= 1000000000000000b ;одни символы +ed_always_focus= 100000000000000b +ed_focus= 10b ;фокус приложения +ed_shift_on= 1000b ;если не установлен -значит впервые нажат shift,если был установлен, значит мы уже что - то делали удерживая shift +ed_shift_on_off=1111111111110111b +ed_shift= 100b ;включается при нажатии на shift т.е. если нажимаю +ed_shift_off= 1111111111111011b +ed_shift_bac= 10000b ;бит для очистки выделеного shift т.е. при установке говорит что есть выделение +ed_shift_bac_cl=1111111111101111b ;очистка при удалении выделения +ed_shift_cl= 1111111111100011b +ed_shift_mcl= 1111111111111011b +ed_left_fl= 100000b +ed_right_fl= 1111111111011111b +ed_offset_fl= 1000000b +ed_offset_cl= 1111111110111111b +ed_insert= 10000000b +ed_insert_cl= 1111111101111111b +ed_mouse_on = 100000000b +ed_mous_adn_b= 100011000b +ed_mouse_on_off=1111111011111111b +ed_height=14 ; высота +macro draw_edit_boxes start,_end,use_f9,procinfo +{ +if use_f9 eq +else + mcall 9,procinfo,-1 +end if + mov edi,start + mov ecx,((_end-start)/ed_struc_size) +@@: + call edit_box.draw + add edi,ed_struc_size + loop @b +} + +macro mouse_edit_boxes start,_end +{ + mov edi,start + mov ecx,((_end-start)/ed_struc_size) +@@: + call edit_box.mouse + add edi,ed_struc_size + loop @b +} + +macro key_edit_boxes start,end +{ + mov edi,start + mov ecx,((end-start)/ed_struc_size) +@@: + call edit_box.key + add edi,ed_struc_size + loop @b +} +ed_struc_size=70 +struc edit_box width,left,top,color,shift_color,focus_border_color,\ + blur_border_color,text_color,max,text,flags,size,pos +{ +.width dd width +.left dd left +.top dd top +.color dd color +.shift_color dd shift_color +.focus_border_color dd focus_border_color +.blur_border_color dd blur_border_color +.text_color dd text_color +.max dd max +.text dd text +.flags dw flags+0 +.size dd size+0 +.pos dd pos+0 +.offset dd 0 +.cl_curs_x dd 0 +.cl_curs_y dd 0 +.shift dd 0 +.shift_old dd 0 +} + + +macro edit_boxes_set_sys_color start,end,color_table +{ + mov edi,start + mov ecx,((end-start)/ed_struc_size) + mov esi,color_table +@@: + mov eax,[esi+36] + mov ebx,[esi+20] + mov ed_focus_border_color,eax + shr bh,1 + shr bl,1 + shr ah,1 + shr al,1 + add ah,bh + add al,bl + ror eax,16 + ror ebx,16 + shr bl,1 + shr al,1 + add al,bl + ror eax,16 + mov ed_blur_border_color,eax + add edi,ed_struc_size + loop @b +} + +macro draw_edit_box ed_ptr,use_f9,procinfo +{ +if use_f9 eq +else + mcall 9,procinfo,-1 +end if + mov edi,ed_ptr + call edit_box.draw +} + +macro mouse_edit_box ed_ptr +{ + mov edi,ed_ptr + call edit_box.mouse +} + +macro key_edit_box ed_ptr +{ + mov edi,ed_ptr + call edit_box.key +} +macro default_box ed_ptr +{ +pusha +; xor eax,eax +; mov ed_shift_pos,eax +; mov ed_shift_pos_old,eax + and word ed_flags,ed_shift_cl +; mov ed_offset,eax +popa +} \ No newline at end of file diff --git a/programs/network/icq/trunk/README.TXT b/programs/network/icq/trunk/README.TXT new file mode 100644 index 0000000000..dbedb85211 --- /dev/null +++ b/programs/network/icq/trunk/README.TXT @@ -0,0 +1,60 @@ +v 0.01 + + +┬хЁёш  ЄхёЄютр , яю¤Єюьє ьэюую эхфюЁрсюЄюъ +ш т√тюф Єё  юЄырфюўэ√х ёююс∙хэш  + +╧юффхЁцштрхЄё : +* ╦юъры№э√щ ъюэЄръЄ-ышёЄ, яюър цхёЄъю чр°шЄ т ъюф +* яхЁхфрўр/яЁшхь ёююс∙хэшщ plain-text +* ╧хЁхъюфшЁютър CP866<->CP1251 +* ╧Ёшхь offline ёююс∙хэшщ +* ╬ЄяЁртър ёююс∙хэш  яюы№чютрЄхы■ эх т ъюэЄръЄ-ышёЄх + /UIN ╤ююс∙хэшх + +═хфюЁрсюЄъш: ╠эюую :-) +* ╬Єъы■ўхэю чръЁ√Єшх ёюъхЄют - ью  VM (Parallels) эруыєїю тшёэхЄ, яЁш + яюя√Єъх чръЁ√Є№ ёюъхЄ + +* ┬ёх ёююс∙хэш  юЄ Ёрчэ√ї ■чхЁют т юфэюь яюых т√тюфр +* ═хы№ч  ёьхэшЄ№ ёЄрЄєё +* ═хы№ч  юЄъы■ўшЄё , юя Є№ цх шч-чр чръЁ√Єш  ёюъхЄют +* ═х яюффхЁцштрхЄё  UTF-8 ш RTF ёююс∙хэш  +* ╚ч шэЇюЁьрЎшш ю ■чхЁх фюёЄєяхэ Єюы№ъю эшъ +* editbox шэюуфр тхфхЄ ёхс  ёЄЁрээю :-) +* .......... + +─ы  шчьхэхэш  єшэр/ярЁюы  эрфю яхЁхъюьяшышЁютрЄ№ яЁюуЁрььє + - Їрщы ki.asm, яхЁхьхээ√х UIN ш PASS + + + +─ы  тэхёхэш  ■чхЁют т ╩╦ - Їрщы comp.inc, ЇєэъЎш  loaduin, +яхЁхьээ√х U1, U2, U3 .... +(╤ъюЁхх тёхую, яюЄюь сєфхЄ яхЁхяшёрэю фы  чруЁєчъш шч Їрщыр) + +╥.ъ.   ЄхёЄшЁютры яЁюуЁрььє Єюы№ъю яюф VM, тючьюцэю, ўЄю эшўхую ш эх чрЁрсюЄрхЄ +╥хёЄшЁютрэшх яЁютюфшыюё№ ё ыюъры№э√ь ёхЁтхЁюь SIQ яюф Windows, VM Parallels +ш ё юёэютэ√ь ёхЁтхЁюь рёш яюф Menuet, VM VMware (Є.ъ. т parallels эхЄ яюффхЁцъш NAT, + р Kolibri эх яюффхЁцштрхЄ ёхЄхтє■ ърЁЄє т VMware, ьюцхЄ,   ш ю°шср■ё№ :-)) + + + + + + +┬√Ёрцр■ сыруюфрЁэюёЄ№ тёхь ЁрчЁрсюЄўшърь OS Kolibri +чр яЁхъЁрёэ√х шэёЄЁєьхэЄ√ ш фюъєьхэЄрЎш■, схч ъюЄюЁющ   с√ +эшўхую эх эряшёры :-) + + + + + + + + + +┬ёх яюцхырэш  ю фры№эхщ°хщ ёєф№сх яЁюхъЄр (чръЁ√Є№, эряЁшьхЁ :-))°ышЄх эр lv4evil@ya.ru + +;╥юы№ъю чр ъЁштющ ъюф ш єцрёэ√щ рэуышщёъшщ эюурьш эх схщЄх :-) \ No newline at end of file diff --git a/programs/network/icq/trunk/build_ru.bat b/programs/network/icq/trunk/build_ru.bat new file mode 100644 index 0000000000..348c888209 --- /dev/null +++ b/programs/network/icq/trunk/build_ru.bat @@ -0,0 +1,2 @@ +@fasm ki.asm ki + diff --git a/programs/network/icq/trunk/comp.inc b/programs/network/icq/trunk/comp.inc new file mode 100644 index 0000000000..cb5481f72a --- /dev/null +++ b/programs/network/icq/trunk/comp.inc @@ -0,0 +1,926 @@ +; +; нарисовать прямоугольник +; x1,y1 ---------| +; | | +; | | +; |-------------x2,y2 +; + macro rect x1, y1, x2, y2, color + { + pushad + + mov edx, color + ; ------------ + mov eax, 38 + mov ebx, x1 + shl ebx, 16 + add ebx, x2 + mov ecx, y1 + shl ecx, 16 + add ecx, y1 + int 40h + + ; ------------ + mov eax, 38 + mov ebx, x1 + shl ebx, 16 + add ebx, x2 + mov ecx, y2 + shl ecx, 16 + add ecx, y2 + int 40h + ; | + ; | + ; | + mov eax, 38 + mov ebx, x1 + shl ebx, 16 + add ebx, x1 + mov ecx, y1 + shl ecx, 16 + add ecx, y2 + int 40h + ; | + ; | + ; | + mov eax, 38 + mov ebx, x2 + shl ebx, 16 + add ebx, x2 + mov ecx, y1 + shl ecx, 16 + add ecx, y2 + int 40h + + popad + } + +; +; Вывод на экран буфера со строками +; + +scbuff db 512*128 dup 0 +; 512 - длина строки +; 128 - количество строк +; +ind db 0 ; Текущий индекс +; +; +x_s dw 15 ; Координаты левого верхнего угла FIXIT +y_s dw 38 ; + +; Высота строки +SH = 10 + +xlen dw 512 ; длина строки +;ylen dw 128 ; количество строк +ylen dw 40 + +;Последние 4 байта в строке обозначают цвет + + printbuff: + pushad + + ; + ; Нарисуем белый прямоугольник + ; + mov eax, 13 + mov ebx, 15*65536+480 + mov ecx, 31*65536+418 + mov edx, 0FFFFFFh + int 40h + + + + xor ecx, ecx ; Счетчик + ;xor eax, eax + xor ebx, ebx + ;xor edx, edx + + pb_loop: + xor edx, edx + xor eax, eax + mov dl, [ind] ; Индекс + mov ax, [ylen] + ;mul edx + cmp ecx, eax + ja pr_end + ; + ; + add edx, ecx ;Прибавим счетчик + xor eax, eax + mov ax, [ylen] + cmp edx, eax ;Индекс меньше количества строк + jna @f ;<= + sub edx, eax ;Если больше, считаем с начала + dec edx + @@: + ; + mov bx, [x_s] ; Координата X + shl ebx, 16 ; + push ecx + mov eax, SH ; Вычисляем местоположение строки + imul eax, ecx ; + ;mov ecx, eax + ;xor eax, eax + + ;mov ax , [x_s] + xor ecx, ecx + mov cx, [y_s] + add ecx, eax + add ebx, ecx ; Координата Y + ; + xor eax, eax + mov ax, [xlen] ;длина строки + imul edx, eax ;Умножаем счетчик на длину строки, получаем смещение относительно начала буфера + ;mov edx, eax + add edx, scbuff + + xor eax, eax + mov ax, [xlen] + sub eax, 4 + xor ecx, ecx + mov ecx, dword [edx+eax] ; Последние 4 Байта с цветом + or ecx, 0x80000000 ; Выводить ASCIIZ + mov eax, 4 + mov esi, -1 ; For Menuet + int 40h + pop ecx + inc ecx + jmp pb_loop + + + pr_end: + popad + ret + +; +; Отладочные сообщения +; + macro write_debug str + { + local ..string, ..label, ..end, ..loop, ..fin + jmp ..label + + ..string db str, 0 + + ..label: + pushad + xor eax, eax + xor ebx, ebx + xor ecx, ecx + xor edx, edx + + mov bl, [ind] + mov ax, [xlen] + imul ebx, eax + add ebx, scbuff + + ..loop: + mov dl, [..string+ecx] + cmp dl, 0 + jz ..end + mov [ebx+ecx], dl + inc ecx + jmp ..loop + + ..end: + mov [ebx+ecx], dl + xor ebx, ebx + mov bl, [ind] + cmp bx, [ylen] + jz @f + inc bl + jmp ..fin + @@: + xor bl, bl + + ..fin: + mov [ind], bl + call printbuff + ;call draw_window + popad + } + +; +; Кнопка +; + macro draw_button x, y, xlen, ylen, id, str + { + pushad + local ..string, ..label + jmp ..label + ..string db str, 0 + + ..label: + mov eax, 8 + mov ebx, x*65536+xlen + mov ecx, y*65536+ylen + mov edx, id + mov esi, 0x4466aa + int 40h + + mov eax, 4 + mov ebx, (x+5)*65536+y+ylen/2-3 + xor ecx, ecx + or ecx, 0x80FFFFFF + mov edx, ..string + int 40h + + popad + } + +; +; Отладочный вывод данных +; + macro data_debug str, rg + { + pushad + local ..string, ..end, ..loop, ..strend, ..fin, ..label + jmp ..label + ..string db str, 20h, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ..strend: + + ..label: + ;xor eax, eax + ;xor ebx, ebx + xor ecx, ecx + xor edx, edx + + mov eax, rg + lea ebx, [..strend-9] + call int2str + + xor eax, eax + xor ebx, ebx + + mov bl, [ind] + mov ax, [xlen] + imul ebx, eax + add ebx, scbuff + + ..loop: + mov dl, [..string+ecx] + cmp dl, 0 + jz ..end + mov [ebx+ecx], dl + inc ecx + jmp ..loop + + ..end: + mov [ebx+ecx], dl + xor ebx, ebx + mov bl, [ind] + cmp bx, [ylen] + jz @f + inc bl + jmp ..fin + @@: + xor bl, bl + + ..fin: + mov [ind], bl + + + + call printbuff + ;call draw_window + + popad + } + +; <--EAX +; -->[ebx] +; + int2str: + pushf + ;push ebx + push ecx + push edx + push esi + + ;xor ebx, ebx + xor ecx, ecx + + i_loop: + mov edx, eax + push ecx + shl ecx, 2 + mov esi, 28 + sub esi, ecx + mov ecx, esi + shr edx, cl + pop ecx + and dl, 0fh ;Отделить младшие 4 бита + cmp dl, 0Ah ;Буква + jnc @f + or dl, 0x30 + jmp i_n1 + + @@: + sub dl, 9 + or dl, 0x40 + i_n1: + mov [ebx+ecx], dl + inc ecx + cmp ecx, 8 + jnz i_loop + + + pop esi + pop edx + pop ecx + ;pop ebx + popf + ret + +; +; +CP866 db 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя' + +; +; Перекодировка из cp1251 в cp866 +; +; [eax] <-- Null-terminated string +; + + win2dos: + pushad + pushf + + xor ebx, ebx + xor ecx, ecx + ;xor edx, edx + + w2d_loop: + mov bl, [eax+ecx] + cmp bl, 0 + jz w2d_end + cmp bl, 0A8h ; Ё + jz w2d_yo1 + cmp bl, 0B8h ; ё + jz w2d_yo2 + cmp bl, 0C0h ; Русская буква + jnc w2d_rchar + inc ecx + jmp w2d_loop + + w2d_yo1: + mov [eax+ecx], byte 0F0h + inc ecx + jmp w2d_loop + + w2d_yo2: + mov [eax+ecx], byte 0F1h + inc ecx + jmp w2d_loop + + w2d_rchar: + sub bl, 0C0h + mov bl, [CP866+ebx] + mov [eax+ecx], bl + inc ecx + jmp w2d_loop + + + w2d_end: + + popf + popad + ret + + +CP1251 db '└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ ' + +; +; Перекодировка из CP866 в CP1251 +; [eax] <-- Null termainated string +; + + dos2win: + pushf + pushad + + xor ebx, ebx + xor ecx, ecx + + dec ecx + + d2w_loop: + inc ecx + mov bl, [eax+ecx] + cmp bl, 0 + jz d2w_end + cmp bl, 80h + jnc d2w_rchar + + ;inc ecx + jmp d2w_loop + + d2w_yo1: + mov byte [eax+ecx], 0A8h + ;inc ecx + jmp d2w_loop + + d2w_yo2: + mov byte [eax+ecx], 0B8h + ;inc ecx + jmp d2w_loop + + d2w_rchar: + cmp bl, 0B0h + jnc d2w_rchar2 + + sub bl, 80h + mov bl, [CP1251+ebx] + mov [eax+ecx], bl + jmp d2w_loop + + d2w_rchar2: + cmp bl, 0E0h + jc d2w_loop + cmp bl, 0F0h + jz d2w_yo1 + cmp bl, 0F1h + jz d2w_yo2 + cmp bl, 0F2h + jnc d2w_loop + add bl, 10h + mov [eax+ecx], bl + jmp d2w_loop + + + d2w_end: + + popad + popf + ret + + +; +; Для вывода сообщений +; [eax] <-- null-terminated string +; ebx <-- color +; + writemsg: + pushad + push ebx + push eax + + xor eax, eax + xor ebx, ebx + + mov bl, [ind] + mov ax, [xlen] + imul ebx, eax + add ebx, scbuff + + pop eax + mov edx, eax + call strlen + mov ecx, eax + mov eax, edx + call strcpy + + mov [ebx+ecx], byte 0x00 + + xor eax, eax + mov ax, [xlen] + sub eax, 4 + pop ecx + mov dword [ebx+eax], ecx ; Последние 4 Байта с цветом + + + xor ebx, ebx + mov bl, [ind] + cmp bx, [ylen] + jz @f + inc bl + jmp ..fin + @@: + xor bl, bl + + ..fin: + mov [ind], bl + + call printbuff + ;call draw_window + + popad + ret + +; +; + + + +; <--EAX Перевод из 16 в 10 форму +; -->[ebx] +; --> eax длина + int2strd: + pushf + ;push ebx + push ecx + push edx + push esi + ;push edi + + ;xor ebx, ebx + xor ecx, ecx + mov esi, 10 + + + id_loop: + xor edx, edx + + div esi + + and dl, 0fh ;Отделить младшие 4 бита + or dl, 0x30 + + mov [ebx+ecx], dl + cmp eax, 10 + inc ecx + jnc id_loop + + and al, 0fh ;Отделить младшие 4 бита + or al, 0x30 + + mov [ebx+ecx], al + ;mov [ebx+ecx+1], byte 0 + inc ecx + mov eax, ecx + ; перевернуть полученную строку + ; + ;xor edx, edx + + ;mov esi, 2 + ;div esi + shr eax, 1 + + xor edx, edx + + id_loop2: + cmp eax, 0 + jz id_end + + + mov dl, [ebx+eax-1] + lea esi, [ebx+ecx] + sub esi, eax + mov dh, [esi] + + mov [ebx+eax-1], dh + mov [esi], dl + + dec eax + jmp id_loop2 + + + + + id_end: + mov eax, ecx + + ;pop edi + pop esi + pop edx + pop ecx + ;pop ebx + popf + ret + +; +; +; +x_bb dw 550 ; Координаты левого верхнего угла +y_bb dw 30 ; +; +bb_width dw 100 ; Ширина кнопок +bb_height dw 15 ; высота кнопок +; +bb_dist dw 10 ; Расстояние между кнопками + +; Идентификаторы кнопок начиная с 100 +; +; Для КЛ +; +; + buttonbox: + pushad + pushf + + xor ecx, ecx + xor eax, eax + xor ebx, ebx + + bb_loop: + + ; Проверяем первый байт уина, если 0, кнопку рисовать не надо + mov ebx, NAME_LEN + imul ebx, ecx + + mov al, [names+ebx] + cmp al, 0 + jz bb_end + ; рисуем кнопку + ; Цвет зависит от статуса UIN + mov ebx, 4 + imul ebx, ecx + mov eax, [stats+ebx] ; В старшем слове дополнительный статус + cmp ax, -1 + jz bb_offline + cmp ax, 1 + jz bb_away + cmp ax, 2 + jz bb_dnd + cmp ax, 4 + jz bb_na + cmp ax, 10h + jz bb_bisy + cmp ax, 20h + jz bb_free4chat + cmp ax, 100h + jz bb_invis + ; Online + mov esi, 0x4466AA + jmp bb_dr + + bb_offline: + mov esi, 0xBEBEBE + jmp bb_dr + + bb_away: + mov esi, 0x14dcc3 + jmp bb_dr + + bb_dnd: + mov esi, 0x14dcc3 + jmp bb_dr + + bb_na: + mov esi, 0x14dcc3 + jmp bb_dr + + bb_bisy: + mov esi, 0x14dcc3 + jmp bb_dr + + bb_free4chat: + mov esi, 0x2233FF + jmp bb_dr + + bb_invis: + mov esi, 0xD0D0D0 + + bb_dr: + + mov bx, [x_bb] + shl ebx, 16 + mov bx, [bb_width] + ;push ecx + mov edx, ecx + lea edx, [edx+100] ; ID + mov edi, ecx + mov cx, [y_bb] + movzx eax, [bb_height] + add ax, [bb_dist] + imul eax, edi + add ecx, eax + shl ecx, 16 + mov cx, [bb_height] + mov eax, 8 + int 40h + + ; + ; Надпись на кнопке + ; + add ebx, 50000h ; Смещение от левого края + shr ecx, 16 + movzx eax, [bb_height] + shr eax, 1 ; /2 + sub eax, 3 ; смещение вверх от центра + add ecx, eax ; + половина размера кнопки + mov bx, cx + mov ecx, 0x80FFFFFF ; Цвет + mov edx, names + mov esi, NAME_LEN + imul esi, edi + add edx, esi + ;mov esi, -1 + mov eax, 4 + int 40h + + mov ecx, edi + inc ecx + cmp ecx, UINS + ja bb_end + jmp bb_loop + + + bb_end: + popf + popad + ret +; +; Массив с UIN +; +UIN_LEN = 11 ; Длина +UINS = 15 ; Количество +; +uins db UIN_LEN*UINS dup 0 +; +; массив со статусами +; +stats dd UINS dup -1 +; +; Массив с именами +; +NAME_LEN = 30 + +names db NAME_LEN*UINS dup 0 + +; +; +U1 db '123456789',0 +U2 db '123456789',0 +U3 db '123456789',0 +; +; Загрузка массива UIN +; + loaduin: + pushad + mov eax, U1 + mov ebx, uins + mov ecx, 9 + call strcpy + + mov ebx, names + call strcpy + + mov eax, U2 + mov ebx, uins+UIN_LEN + mov ecx, 9 + call strcpy + + mov ebx, names+NAME_LEN + call strcpy + + mov eax, U3 + mov ebx, uins+UIN_LEN*2 + mov ecx, 9 + call strcpy + + mov ebx, names+NAME_LEN*2 + call strcpy + + + popad + ret + +; +; Функция для загрузки КЛ никами и статусами +; eax <-- Номер уина по порядку в массиве uins, начиная с 0 +; [ebx] <-- указатель на null-terminated строку с новым именем +; ecx <-- Новый статус +; + loadbb: + pushad + pushf + ; + ; Проверяем номер + ; + cmp eax, UINS + jnc loadbb_end ;>= + + + ; + ; Удаляем кнопку + ; + push ecx + push ebx + push eax + + lea edx, [eax+100] + or edx, 0x80000000 + mov eax, 8 + int 40h + + ; + ; Сохраняем новый статус в массиве статусов + ; + pop eax + mov edx, 4 ; DWORD + imul edx, eax + mov [stats+edx], ecx + ; + ; Сохраняем новое имя + ; + mov edi, eax ; edi <-- Uin number + pop eax ; <-- offset of string + mov ebx, eax + call strlen + mov ecx, eax ; Len + + + mov eax, ebx ;Source + mov edx, NAME_LEN + imul edx, edi + lea ebx, [names+edx] ; Dest + call strcpy + mov [names+edx+ecx], byte 0 + + xchg edi, eax ; eax - счетик, edi - указатель на строку + + pop ecx + push edi + ; рисуем кнопку + ; Цвет зависит от статуса UIN + + cmp cx, -1 + jz l_offline + cmp cx, 1 + jz l_away + cmp cx, 2 + jz l_dnd + cmp cx, 4 + jz l_na + cmp cx, 10h + jz l_bisy + cmp cx, 20h + jz l_free4chat + cmp cx, 100h + jz l_invis + ; Online + mov esi, 0x4466AA + jmp l_dr + + l_offline: + mov esi, 0xBEBEBE + jmp l_dr + + l_away: + mov esi, 0x14dcc3 + jmp l_dr + + l_dnd: + mov esi, 0x14dcc3 + jmp l_dr + + l_na: + mov esi, 0x14dcc3 + jmp l_dr + + l_bisy: + mov esi, 0x14dcc3 + jmp l_dr + + l_free4chat: + mov esi, 0x2233FF + jmp l_dr + + l_invis: + mov esi, 0xD0D0D0 + + l_dr: + + mov bx, [x_bb] + shl ebx, 16 + mov bx, [bb_width] + ;push ecx + mov edx, eax + lea edx, [edx+100] ; ID + mov edi, eax + mov cx, [y_bb] + movzx eax, [bb_height] + add ax, [bb_dist] + imul eax, edi + add ecx, eax + shl ecx, 16 + mov cx, [bb_height] + mov eax, 8 + int 40h + + ; + ; Надпись на кнопке + ; + add ebx, 50000h ; Смещение от левого края + shr ecx, 16 + movzx eax, [bb_height] + shr eax, 1 ; /2 + sub eax, 3 ; смещение вверх от центра + add ecx, eax ; + половина размера кнопки + mov bx, cx + mov ecx, 0x80FFFFFF ; Цвет + pop edx + mov esi, -1 + mov eax, 4 + int 40h + + + + loadbb_end: + + popf + popad + ret \ No newline at end of file diff --git a/programs/network/icq/trunk/config.inc b/programs/network/icq/trunk/config.inc new file mode 100644 index 0000000000..4be62cc03b --- /dev/null +++ b/programs/network/icq/trunk/config.inc @@ -0,0 +1 @@ +__CPU_type fix p5 diff --git a/programs/network/icq/trunk/editbox.mac b/programs/network/icq/trunk/editbox.mac new file mode 100644 index 0000000000..47689a12f0 --- /dev/null +++ b/programs/network/icq/trunk/editbox.mac @@ -0,0 +1,1078 @@ +;Макрос для вывода основных функций которые испльзуются боксом +macro use_general_func +{ +;debug_func +;---------------------------------------------------------- +;--- процедура прорисовки выделеной части ----------------- +;---------------------------------------------------------- +.draw_shift: + test word ed_flags,ed_shift_bac ;установка флага, выделенной области + jz @f + mov ebp,shift_color + mov ebx,dword ed_shift_pos + call .sh_cl_ +@@: ret +;---------------------------------------------------------- +;--- процедура прорисовки текста -------------------------- +;---------------------------------------------------------- +.draw_text: +;--- вычисляем, сколько помещается символов --- +;--- чтобы мусор не рисовать --- + call .get_n + mov esi,ed_size + mov ebx,ed_offset + sub esi,ebx + cmp eax,esi + jae @F + mov esi,eax ;чтобы не выходить за пределы экрана +;--- рисуем текст --- +@@: mov eax,4 + mov ebx,ed_left + mov edx,ed_offset + add ebx,2 + shl ebx,16 + mov bx,ed_top + add ebx,4 + mov ecx,ed_text_color + add edx,ed_text + mcall +ret +;---------------------------------------------------------- +;--- процедура прорисовки фона ---------------------------- +;входные данные +;eax +;edx - color +;---------------------------------------------------------- +;вход только цвет edx +.draw_bg: + mov ebx,ed_left + add ebx,1 + shl ebx,16 + mov bx,ed_width + sub ebx,1 + mov edx,ed_color +.draw_bg_eax: + mov ecx,ed_top + mov eax,13 + add ecx,1 + shl ecx,16 + mov cx,ed_height + dec ecx + mcall +ret + +;---------------------------------------------------------- +;--- процедура получения количества символов в текущей щирине компонента +;---------------------------------------------------------- +.get_n: + mov eax,ed_width ;получем ширину компонента + xor edx,edx ;результат распологается в паре edx:eax в eax - остаток + sub eax,4 ;вычтим 4 + mov ebx,6 ;загрузми делитель + div ebx ;размделим на 6 +ret +;---------------------------------------------------------- +;--- процедура рисования курсора -------------------------- +;---------------------------------------------------------- +;входные ebp- цвет +.clear_cursor: + mov edx,ebp + mov ebx,cl_curs_x + mov ecx,cl_curs_y + jmp .draw_curs +.draw_cursor: + mov edx,ed_text_color + mov ebx,ed_pos + mov ecx,ed_offset + sub ebx,ecx + + lea ebx,[ebx*2+ebx] + shl ebx,1 + ;imul ebx,6 + add bx,ed_left + mov ecx,ed_top + inc ebx + add ecx,2 + mov ebp,ebx + shl ebx,16 + mov bx,bp + mov ebp,ecx + + shl ecx,16 + mov cx,bp + add cx,ed_height-4 + + mov cl_curs_x,ebx + mov cl_curs_y,ecx +.draw_curs: + mcall 38 +ret +;---------------------------------------------------------- +;--- процедура рисования рамки ---------------------------- +;---------------------------------------------------------- +.draw_border: +;--- цвет рамки --- + test word ed_flags,ed_focus + mov edx,ed_focus_border_color + jne @f + mov edx,ed_blur_border_color +@@: +;--- сверху --- + mov eax,38 + mov ebx,ed_left + mov ecx,ebx + shl ebx,16 + mov bx,cx + add bx,ed_width + mov ecx, ed_top + mov esi,ecx + shl ecx,16 + mov cx,si + mcall +;--- снизу --- + mov esi,ecx + add ecx,ed_height + mov ebp,ecx + shl ecx,16 + mov cx,bp + mcall +;--- слева --- + mov cx,si + mov ebp,ebx + sub bx,ed_width + mcall +;--- справа --- + mov ebx,ebp + shl ebx,16 + mov bx,bp + mcall +ret +;---------------------------------------------------------- +;--- проверка, зашел ли курсор за границы и, если надо, --- +;--- изменяем смещение ------------------------------------ +;--- если смещение было установка флага ed_offset_cl иначе +; если ничего не изменилось то выставление ed_offset_fl +; в общей битовой маррице состояния компонентов word ed_flags +;---------------------------------------------------------- +.check_offset: +pusha + mov ecx,ed_pos + mov ebx,ed_offset + cmp ebx,ecx + ja .sub_8 + + push ebx + call .get_n ;получим кол-во символов в паре регистров edx:eax + pop ebx + mov edx,ebx + add edx,eax ;ed_offset+width editbox + inc edx ;необходимо для номального положения курсора в крайней левой позиции + cmp edx,ecx + ja @f + + mov edx,ed_size + cmp edx,ecx + je .add_end + + sub edx,ecx + cmp edx,8 + jbe .add_8 + add ebx,8 + jmp .chk_d + +.sub_8: cmp ecx,0 + je .sub_min + cmp ebx,8 + jbe .sub_min + sub ebx,8 ;ebx=ed_offset + jmp .chk_d +.sub_min: + xor ebx,ebx + jmp .chk_d + +.add_end:sub edx,eax + mov ebx,edx + jmp .chk_d +.add_8: add ebx,edx +.chk_d: mov ed_offset,ebx + call .draw_bg + and word ed_flags,ed_offset_cl +edit_ex +@@: + or word ed_flags,ed_offset_fl +edit_ex +} + +macro use_key_func +{ +;Обработка Shift для снятия выделения неизвестной области +.shift: ;;;;;;;SHIFT + test word ed_flags,ed_shift + je .f_exit + +@@: mov ebp,shift_color + or word ed_flags,ed_shift_bac ;установка флага, выделенной области + mov ebx,dword ed_shift_pos + call .sh_cl_ + jmp .draw_cursor_text +;;;;;;;;;;;;;;;;;;;;; +.f_exit:call .check_offset + and word ed_flags,ed_shift_cl + call .enable_null + jmp .draw_cursor_text +.sh_cl_: +;;;;;;SHIFT end +;обработка очистки, при левом - правом движении выделения +;для обработки снятия выделения +;входные параметры ebp=color ebx=ed_shift_pos + mov eax,dword ed_pos + cmp eax,ebx + + jae .sh_n + push eax ;меньшее в eax + push ebx ;большее + jmp .sh_n1 + ;если иначе +.sh_n: push ebx + push eax +.sh_n1: + call .check_offset + call .get_n + mov edx,eax ;size of ed_box + mov ecx,ed_offset + add eax,ecx ;eax = w_off= ed_offset+width + mov edx,eax ;save + pop ebx ;большее + pop eax ;меньшее + + cmp eax,ecx ;сравнение с меньшего с offset. + jae .f_f ;если больше + xor eax,eax + cmp edx,ebx ;cравним размер w_off с большим + jb @f + sub ebx,ecx + jmp .nxt_f +@@: mov ebx,edx + sub ebx,ecx + jmp .nxt_f +.f_f: + sub eax,ecx + cmp edx,ebx ;cравним размер w_off с большим + jle @f + sub ebx,ecx + sub ebx,eax + jmp .nxt_f +@@: + mov ebx,edx + sub ebx,ecx + sub ebx,eax +.nxt_f: + mov edx,ebx + lea ebx,[eax*2+eax] + shl ebx,1 + add ebx,ed_left + inc ebx + shl ebx,16 + lea ecx,[edx*2+edx] + shl ecx,1 + mov bx,cx + inc ebx + mov edx,ebp;shift_color + + call .draw_bg_eax +@@: call .enable_null + ret +;;;;;;;;;;;;;;;;;;;;; +;Установка- снятие выделения в один символ +;;;;;;;;;;;;;;;;;;;;; +.drw_sim: + mov eax,dword ed_pos + call .draw_rectangle ;нарисовать прямоугольник с заданным цветом + jmp @b +;;;;;;;;;;;;;;;;;;;;; +;Фукция установки выделения при движения влево и вправо и нажатии shift +;Логика: +;;;;;;;;;; +.draw_wigwag: +;функция установки переменных + mov ebp,shift_color + call .clear_cursor + + or word ed_flags,ed_shift_bac ;установка флага, выделенной области + mov ebp,shift_color + mov eax,dword ed_pos + test word ed_flags,ed_left_fl + jz .low + jmp @f +;;;;;;;;;; +;Фукция удаления выделения при движения влево и вправо и нажатии shift +;Логика: +;;;;;;;;;; +.draw_wigwag_cl: +;функция установки переменных + mov ebp,ed_color + call .clear_cursor + + mov ebp,ed_color + mov eax,dword ed_pos + test word ed_flags,ed_left_fl + jz .low +@@: call .draw_rectangle ;нарисовать прямоугольник закрашиваемой области + ret +.low: dec eax + jmp @b +;входной параметр ebx - ed_pos +.sh_first_sh: + test word ed_flags,ed_shift + je @f + mov dword ed_shift_pos_old,ebx + test word ed_flags,ed_shift_on + jne @f + mov dword ed_shift_pos,ebx + or word ed_flags,ed_shift_on +@@: ret +;Обработка крайних положений в editbox при нажатом shift +;производит снятие выделение, если нет shift +;иначе вообще выходит +.sh_st_of: + test word ed_flags,ed_shift + jne @f + test word ed_flags,ed_shift_bac + je @f + mov ebp,ed_color + mov ebx,dword ed_shift_pos + call .sh_cl_ ;очистка выделеного фрагмента + and word ed_flags,ed_shift_cl ; очистка от того что убрали выделение + jmp .draw_cursor_text +@@: + and word ed_flags,ed_shift_off +edit_ex +;проверка состояния shift был ли он нажат раньше? +.sh_enable: + test word ed_flags,ed_shift + jne .sh_ext_en ;нарисовать закрашеный прямоугольник + + test word ed_flags,ed_shift_bac + je @f + call .check_offset + + mov ebp,ed_color + mov ebx,dword ed_shift_pos + call .sh_cl_ ;очистка выделеного фрагмента + call .draw_wigwag_cl + and word ed_flags,ed_shift_cl ; 1вар не нужно + ret + +@@: mov ebp,ed_color + call .clear_cursor + call .check_offset + ret +.sh_ext_en: + call .check_offset + test word ed_flags,ed_offset_fl + je @f +;Рисование закрашеных прямоугольников и очистка их + mov eax,dword ed_shift_pos + mov ebx,dword ed_pos + mov ecx,dword ed_shift_pos_old +;проверка и рисование закрашеных областей + cmp eax,ecx + je .1_shem + jb .smaller + cmp ecx,ebx + ja .1_shem + call .draw_wigwag_cl ;clear + jmp .sh_e_end +.smaller: + cmp ecx,ebx + jb .1_shem + call .draw_wigwag_cl ;clear + jmp .sh_e_end +;alike = +.1_shem: call .draw_wigwag +.sh_e_end: and word ed_flags,ed_shift_off + ret +@@: mov ebp,shift_color + mov ebx,dword ed_shift_pos + call .sh_cl_ + jmp .sh_e_end +;функция для обработки shift при нажатии home and end +.sh_home_end: + mov ebp,ed_color + call .clear_cursor + test word ed_flags,ed_shift_bac + je @f + mov ebp,ed_color + mov ebx,dword ed_shift_pos_old + call .sh_cl_ + +@@: test word ed_flags,ed_shift + je .sh_exit_ ;выйти + mov ebp,shift_color + mov ebx,dword ed_shift_pos + call .sh_cl_ + or word ed_flags,ed_shift_bac ;установка флага, выделенной области + jmp .sh_e_end +.sh_exit_: call .check_offset + ret +;функция внесения 0 по адресу ed_size+1 +.enable_null: + pusha + mov eax,ed_size + mov ebx,ed_text + test eax,eax + add eax,ebx + jne @f + inc eax +@@: xor ebx,ebx + mov [eax],bl +edit_ex +;- удаление символа +;Входные данные edx=ed_size;ecx=ed_pos +.del_char: + mov esi,ed_text + test word ed_flags,ed_shift_on + je @f + mov eax,dword ed_shift_pos + mov ebx,esi + cmp eax,ecx + jae .dh_n + + mov ed_pos,eax ;что бы не было убегания курсора + mov ebp,ecx + sub ebp,eax + add ebx,eax ;eax меньше + sub edx,ecx + add esi,ecx + + mov dword ed_shift_pos,ebp + jmp .del_ch_sh + ;если иначе +.dh_n: + mov ebp,eax + sub ebp,ecx + add ebx,ecx + sub edx,eax + add esi,eax + mov dword ed_shift_pos,ebp + jmp .del_ch_sh + +@@: add esi,ecx ;указатель + смещение к реальному буфферу + mov ebx,esi + inc esi + cld + + sub edx,ecx +.del_ch_sh: + + push edi + mov edi,ebx +@@: + lodsb + stosb + dec edx + jns @b + + pop edi + ret +;вычислить закрашиваемую область +;соглашение в ebp - передается ed_size +.clear_bg: + call .get_n ;получить размер в символах ширины компонента + push eax + mov ebx,ed_offset + add eax,ebx ;eax = w_off= ed_offset+width + mov ebx,ebp ;ed_size + + cmp eax,ebx + jb @f + mov eax,ed_pos + sub ebx,eax + mov ecx,ed_offset + sub eax,ecx + jmp .nxt +@@: mov ebx,ed_pos + push ebx + sub eax,ebx + mov ebx,eax ;It is don't optimal + + pop eax ;ed_pos + mov ecx,ed_offset + sub eax,ecx +.nxt: + mov ebp,eax ;проверка на выход закрашиваемой области за пределы длины + add ebp,ebx + pop edx + cmp ebp,edx + je @f + inc ebx + +@@: mov edx,ebx + lea ebx,[eax*2+eax] + shl ebx,1 + add ebx,ed_left + inc ebx + shl ebx,16 + lea ecx,[edx*2+edx] + shl ecx,1 + mov bx,cx + mov edx,ed_color + call .draw_bg_eax + ret +;;;;;;;;;;;;;;;;;;; +;;; Обработка примитивов +;;;;;;;;;;;;;;;;;;;; +;Нарисовать прямоугольник, цвет передается в ebp +;входные параметры: +;eax=dword ed_pos +;ebp=-цвет ed_color or shift_color +.draw_rectangle: + mov ecx,dword ed_offset + sub eax,ecx + lea ebx,[eax*2+eax] + shl ebx,1 + inc ebx + add ebx,ed_left + shl ebx,16 + mov bx,6 + mov edx,ebp + call .draw_bg_eax + ret +;;;;;;;;;;;;;;;;;; +;;Проверка нажат ли shift +;;;;;;;;;;;;;;;;;; +.check_shift: +pusha ;сохраним все регистры + mcall 66,3,1 + test al,0x03 + je @f + or word ed_flags,ed_shift ;установим флаг +@@:edit_ex +} +;макрос клавиш на которые происходит реакция +macro use_key_process backspase,delete,left,right,home,end,insert +{ +if backspase eq +else + cmp ah,8 + jz .backspace +end if +if delete eq +else + cmp ah,0xb6 + jz .delete +end if +if left eq +else + cmp ah,176 + jz .left +end if +if right eq +else + cmp ah,179 + jz .right +end if +if home eq +else + cmp ah,180 + jz .home +end if +if home eq +else + cmp ah,181 + jz .end +end if +if insert eq +else + cmp ah,185 ;insert + jz .insert +end if +} +macro use_key_no_process up,down,esc +{ +if up eq +else + cmp ah,177 + jz .editbox_exit +end if +if down eq +else + cmp ah,178 + jz .editbox_exit +end if +if esc eq +else + cmp ah,27 ;ESC - клавиша )) + jz .editbox_exit +end if +} + +macro use_key_figures_only +{ + test word ed_flags,ed_figure_only ; только цифры ? + jz @f + cmp ah,'0' + jb .editbox_exit + cmp ah,'9' + ja .editbox_exit +@@: +} +macro are_key_shift_press +{ + test word ed_flags,ed_shift_on + je @f + ;Входные данные edx=ed_size;ecx=ed_pos + push eax + mov edx,ed_size + mov ecx,ed_pos + pusha +;;;;;;;;;;;;;;;;;;;;; + mov ebp,ed_color + mov ebx,dword ed_shift_pos + call .sh_cl_ +;;;;;;;;;;;;;;;;;;;;; + popa + call .del_char +;;;; + mov eax,dword ed_shift_pos + mov ebx,ed_size + sub ebx,eax + mov ed_size,ebx + pop eax +@@: +} +macro are_key_cur_end +{ + mov ecx,ed_size + mov edx, ed_max + test word ed_flags,ed_insert + jne @f + cmp ecx,edx + jae .editbox_exit +@@: mov ebx, ed_pos + cmp ebx,edx + jl @f ; если меньше или равно + jmp .editbox_exit + +@@: ; сдвигаем символы после курсора вправо + mov ecx,ed_size + push edi eax + mov ebp,edi + mov esi,ed_text ; Указатель на буфер + ;Будем работать со строкой + add esi,ecx ;add ed_size добавим max size + mov edi,esi + + cmp ecx,ebx ;Если у нас позиция курсора = текущему размеру напечатанных символов т.е. курсор стоит в конце + je .In_k + + test word [ebp+40],ed_insert ;IF insert is enable т.к. edi изменен адресуем через ebp + jne .ins_v +;clear +pusha + mov edi,ebp + mov ebp,ed_size + call .clear_bg +popa + sub ecx,ebx ;Найдем кол-во символов для передвижения. + inc edi ;Сместим наши символы в право + std + inc ecx + @@: + ;-------- + lodsb + stosb + ;-------- + loop @b +.In_k: cld + pop eax + mov al,ah + stosb + pop edi +; вставляем код клавиши туда, где курсор + ; увеличиваем значение размера и позиции + inc dword ed_size + inc dword ed_pos + call .draw_all2 + jmp .shift +} +macro use_work_key +{ +.insert: test word ed_flags,ed_insert ;not word ed_insert + je @f + and word ed_flags,ed_insert_cl + jmp .editbox_exit +@@: + or word ed_flags,ed_insert + jmp .editbox_exit +.ins_v: + dec dword [ebp+42];ed_size ;processing is insert + sub esi,ecx + add esi,ebx + mov edi,esi +;clear +pusha + mov edi,ebp + mov ebp,ed_pos + call .clear_bg +popa + jmp .In_k +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.delete: + mov edx,ed_size + mov ecx,ed_pos + cmp edx,ecx + jg .bac_del + test word ed_flags,ed_shift_on + jne .del_bac +edit_ex +.bac_del: + call .del_char + jmp .draw_all +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;--- нажата клавиша backspace --- +.backspace: + ; проверяем, курсор у левого края ? + mov ecx,ed_pos + test ecx,ecx + jnz .del_bac + test word ed_flags,ed_shift_on + jne .bac_del + +edit_ex +.del_bac: + mov edx,ed_size + cmp edx,ecx ;if ed_pos=ed_size + je @f + dec ecx + call .del_char +@@: test word ed_flags,ed_shift_on + jne .bac_del + dec dword ed_pos +.draw_all: + push .shift;.draw_cursor_text;eax + + test word ed_flags,ed_shift_on + je @f + mov eax,dword ed_shift_pos + mov ebx,ed_size + sub ebx,eax + mov ed_size,ebx + + mov ebp,ed_color + call .clear_cursor + call .check_offset + call .draw_bg + ret +@@: dec dword ed_size + +.draw_all2: + and word ed_flags,ed_shift_cl + mov ebp,ed_color + call .clear_cursor + call .check_offset + mov ebp,ed_size + call .clear_bg + ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;--- нажата клавиша left --- +.left: mov ebx,ed_pos + test ebx,ebx + jz .sh_st_of + or word ed_flags,ed_left_fl + call .sh_first_sh + dec dword ed_pos + call .sh_enable + jmp .draw_cursor_text +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;--- нажата клавиша right --- +.right: mov ebx,ed_pos + cmp ebx,ed_size + je .sh_st_of + and word ed_flags,ed_right_fl + call .sh_first_sh + inc dword ed_pos + call .sh_enable + jmp .draw_cursor_text +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.home: + mov ebx,ed_pos + test ebx,ebx + jz .sh_st_of + call .sh_first_sh + xor eax,eax + mov ed_pos,eax + call .sh_home_end + jmp .draw_cursor_text +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.end: + mov ebx,ed_pos + cmp ebx,dword ed_size + je .sh_st_of + call .sh_first_sh + mov eax,ed_size + mov ed_pos,eax + call .sh_home_end + jmp .draw_cursor_text +} + +macro use_mouse_func scr_w +{ +;---------------------------------------------------------- +;--- Обработка .mouse_wigwag +;---------------------------------------------------------- +.mouse_wigwag: + shr eax,16 + or word ed_flags,ed_shift_bac+ed_shift_on+ed_shift +;;;;;;;;;;;;;;;;;; +;;процедура обработки положения выделенного текста, когда происходит выход за пределы editbox +;;;;;;;;;;;;;;;;;; + mov ebx,[procinfo.box.left] + add ebx,ed_left +if scr_w eq +else + add ebx,dword scr_w +end if + cmp eax,ebx + jb .mleft + + add ebx,ed_width + cmp eax,ebx + ja .mright + + sub ebx,ed_width + + xor edx,edx + sub eax,ebx ; вычтим из координат мышки по оси х координаты до editbox по оси х + mov ebx,6 + div ebx +;;;;;;;;;;;;;;;;;; +;;процедура обработки положения выделенного текста, в пределах области editbox +;;;;;;;;;;;;;;;;;; +;Получили координаты в eax мышки, т.е. куда она переместилась +;Рисование закрашеных прямоугольников и очистка их + add eax,ed_offset ;добавим смещение + cmp eax,dword ed_size ;если вышли за пределы, то ничего не делать + ja .mwigvag +.mdraw: + mov dword ed_pos,eax ;сохраним новое значение +;Рисование закрашеных прямоугольников и очистка их + mov ecx,dword ed_shift_pos + mov ebx,dword ed_shift_pos_old + mov dword ed_shift_pos_old,eax ;внесем новое значение старой позиции курсора +;проверка и рисование закрашеных областей + cmp ecx,ebx ;выясняем куда было движение на один шаг назад + je .m1_shem ;движения не было ранее + jb .msmaller ;движение было -> + cmp ebx,eax ;движение было до этого <- и тут мы проверяем сейчас куда движение происходит + ja .m1_shem ;если было движение <- то нужно закрасить область + je .mwigvag ;если изменения не было, то ничего не делать + mov ebp,ed_color ;тут нужно очистить область c ed_pos ed_shift_pos_old +;входные параметры ebp=color ebx=ed_shift_pos + call .sh_cl_ + jmp .mwigvag +.msmaller: + cmp ebx,eax + jb .m1_shem + mov ebp,ed_color +;входные параметры ebp=color ebx=ed_shift_pos + call .sh_cl_ + jmp .mwigvag +;alike = +.m1_shem: + mov ebp,shift_color +;входные параметры ebp=color ebx=ed_shift_pos + mov ebx,ecx + call .sh_cl_ + jmp .mwigvag +.mwigvag: + and word ed_flags,ed_shift_mcl + jmp .draw_cursor_text +; popa +; ret +.mleft: + mov eax,ed_pos + cmp eax,0 + jbe .mwigvag + dec eax + call .check_offset + push eax + mov ebx,ed_shift_pos + mov ebp,shift_color + call .sh_cl_ + pop eax + jmp .mdraw +.mright: + mov eax,ed_pos + mov ebx,ed_size + cmp eax,ebx + jae .mwigvag + inc eax + call .check_offset + mov ebx,ed_shift_pos + mov ebp,shift_color + push eax + call .sh_cl_ + pop eax + jmp .mdraw +} + +macro use_work_mause scr_h,scr_w +;---------------------------------------------------------- +;--- А не удерживаем ли мы клавишу мышки, перемещая курсор, во все разные стороны? +;---------------------------------------------------------- +{ + test word ed_flags,ed_mouse_on + jne .mouse_wigwag +;---------------------------------------------------------- +;--- проверяем, попадает ли курсор в edit box ------------- +;---------------------------------------------------------- + mov ebx,[procinfo.box.top] + add ebx,ed_top +if scr_h eq +else + add ebx,scr_h +end if + cmp ax,bx + jl ._blur;.mouse_end_no_focus + + add ebx,ed_height + cmp ax,bx + jg ._blur;.mouse_end_no_focus + + shr eax,16 + + mov ebx,[procinfo.box.left] + add ebx,ed_left +if scr_w eq +else + add ebx,scr_w +end if + cmp ax,bx + jl ._blur;.mouse_end_no_focus + + add ebx,ed_width + cmp ax,bx + jg ._blur;.mouse_end_no_focus +;--- изменяем позицию курсора --- + push eax + mov ebp,ed_color + call .clear_cursor + pop eax +._mvpos: + mov ebx,dword [procinfo.box.left] + xor edx,edx + sub eax,ed_left + sub eax,ebx +if scr_w eq +else + add ebx,scr_w + sub eax,2 +end if + mov ebx,6 + div bx + add eax,ed_offset + cmp eax,ed_size + jna ._mshift + mov eax,ed_size +._mshift: +;;;;;;; +;;Секция обработки shift и выделения по shift +;;;;;;; + test word ed_flags,ed_shift_bac + je @f + mov ebp,dword ed_color + mov ebx,dword ed_shift_pos + push eax + call .sh_cl_ + and word ed_flags,ed_shift_bac_cl + pop eax +@@: + test word ed_flags,ed_mouse_on + jne @f + + mov dword ed_shift_pos,eax + or word ed_flags,ed_mouse_on + mov dword ed_pos,eax + mov dword [mouse_flag],edi ;установим идентификатор + bts word ed_flags,1 ;установка фокуса + jmp .m_sh +@@: + cmp eax,dword ed_shift_pos ;если позиции не изменились + je .editbox_exit + mov ed_pos,eax + mov ebp,dword shift_color + mov ebx,dword ed_shift_pos + call .sh_cl_ + or word ed_flags,ed_mous_adn_b ;установим бит что мы выделили +shift_on + +.m_sh: call .draw_text + call .draw_cursor +;---------------------------------------------------------- +;--- процедура установки фокуса --------------------------- +;---------------------------------------------------------- + jmp .drc +._blur: + test word ed_flags,ed_always_focus + jne .editbox_exit + btr word ed_flags,1 ; если не в фокусе, выходим + jnc .editbox_exit + + mov ebp,ed_color + call .clear_cursor +.drc: call .draw_border + jmp .editbox_exit +} + + +; Макрос выхода +macro edit_ex +{ +popa +ret +} +macro debug +{ + ;----------- отладка + pushad +; mov dword [ed_buffer.2],0 +; mov eax,edi + mov eax,dword [ed_buffer.2] + mov edi,ed_buffer.3 + call .str + ;рисование фона + mov eax,13 + mov ebx,178*65536+70 + mov ecx,28*65536+10 + xor edx,edx + int 0x40 + ;вывод значения на экран + mov eax,4 + mov ebx,180*65536+30 + mov ecx,0x10DDBBCC + mov edx,ed_buffer.3 + mov esi,8 + int 0x40 + popad + ;----------- отладка +} +macro debug_func +{ +.str: + mov ecx,0x0a ;задается система счисления изменяются регистры ebx,eax,ecx,edx входные параметры eax - число + ;преревод числа в ASCII строку взодные данные ecx=система счисленя edi адрес куда записывать, будем строку, причем конец переменной + cmp eax,ecx ;сравнить если в eax меньше чем в ecx то перейти на @@-1 т.е. на pop eax + jb @f + xor edx,edx ;очистить edx + div ecx ;разделить - остаток в edx + push edx ;положить в стек + ;dec edi ;смещение необходимое для записи с конца строки + call .str;перейти на саму себя т.е. вызвать саму себя и так до того момента пока в eax не станет меньше чем в ecx + pop eax + @@: ;cmp al,10 ;проверить не меньше ли значение в al чем 10 (для системы счисленя 10 данная команда - лишная)) + ;sbb al,$69 ;- честно данная инструкция меня заставляет задуматься т.е. я не знаю как это работает + ;das ;после данной команды как бы происходит уменьшение al на 66h (в книге написано другое) + or al,0x30 ;данная команда короче чем две выше + stosb ;записать элемент из регистра al в ячеку памяти es:edi + + ret ;вернуться чень интересный ход т.к. пока в стеке храниться кол-во вызовов то столько раз мы и будем вызываться +} \ No newline at end of file diff --git a/programs/network/icq/trunk/ki.asm b/programs/network/icq/trunk/ki.asm new file mode 100644 index 0000000000..83fb5bbf39 --- /dev/null +++ b/programs/network/icq/trunk/ki.asm @@ -0,0 +1,3496 @@ +; <--- description ---> +; compiler: FASM 1.67.21 +; name: ICQ for Kolibri +; version: 0.01 +; written by: LV +; e-mail: lv4evil@ya.ru + + +; <--- include all MeOS stuff ---> +include "lang.inc" +include "MACROS.INC" +purge mov +;include "ASCL9/ascl.inc" +;include "debug.inc" +include "editbox.inc" + +; <--- start of MenuetOS application ---> +MEOS_APP_START + +;include "debug.inc" +include "2000.inc" +include "comp.inc" + +use_edit_box procinfo,22,5 + +; <--- start of code ---> +CODE + + + ;mov eax, 40 + ;mov ebx, 47h + ;int 40h + + call loaduin + call draw_window ; at first create and draw the window + + ;call buttonbox + + wait_event: ; main cycle + mov eax, 23 + mov ebx, 20 + int 0x40 + + cmp eax, 1 ; if event == 1 + je redraw ; jump to redraw handler + cmp eax, 2 ; else if event == 2 + je key ; jump to key handler + cmp eax, 3 ; else if event == 3 + je button ; jump to button handler + + ; + ; Ждем данных + ; + mov eax, 53 + mov ebx, 2 + push ecx + mov ecx, [socket] + int 0x40 + pop ecx + cmp eax, 0 + jnz read_socket + + mouse_edit_box inputbox + ; + ; Если есть соединение с сервером, посылаем пакеты - подтвеждения каждые 60 с + ; + call sendkeep + + jmp wait_event ; else return to the start of main cycle + + + redraw: ; redraw event handler + call draw_window + jmp wait_event + + + key: ; key event handler + mov eax, 2 ; get key code + int 0x40 + + cmp ah, 0Dh ; Пробел - отправить сообщение + jz send + + + key_edit_box inputbox + + jmp wait_event + + + button: ; button event handler + mov eax, 17 ; get button identifier + int 0x40 + + cmp ah, 2 + jz connect + + cmp ah, 3 + jz disconnect + + cmp ah, 4 + jz send + + ; + ; Проверяем, не нажата ли кнопка в КЛ + ; 100 2 символов, считается, что передан + ; сам уин - для отправки сообщений юзерам, которых нет в КЛ + ; + mov al, [inputbuff] + cmp al, '/' + jnz sd_message + ; Смена уина + ;mov al, [inputbuff+2] + ;cmp al, 20h + ;jz sd_use_kl + mov al, [inputbuff+3] + cmp al, 20h ; Пробел + jz sd_use_kl + ; + ; Ищем первый пробел, им должен закончиться уин + ; + xor ecx, ecx + sd_loop: + mov al, [inputbuff+ecx] + cmp al, 20h + jz sd_space + cmp al, 0 + jz wait_event + inc ecx + jmp sd_loop + + sd_space: + ; + ; Заменяем пробел на 0, отсылаем сообщение + mov [inputbuff+ecx], byte 0 + lea ebx, [inputbuff+1] + lea eax, [inputbuff+ecx+1] + call sendmsg + mov ebx, 0000FFh + call writemsg + jmp wait_event + + + + sd_use_kl: + lea eax, [inputbuff+1] + mov [inputbuff+3], byte 0 + call ascitoint + lea eax, [eax-1] ; Т.к. в КЛ отсчет с 0 + mov [curruser], al + + + sd_message: + ; + ; Сообщение + movzx eax, [curruser] + mov ebx, UIN_LEN + imul ebx, eax + lea ebx, [uins+ebx] + mov al, [inputbuff] + cmp al, '/' + jz @f + mov eax, inputbuff + jmp sd_send + @@: + ;mov al, [inputbuff+2] + ;cmp al, ' ' + ;jz @f + lea eax, [inputbuff+4] + ;jmp sd_send + ;@@: lea eax, [inputbuff+3] + + sd_send: + call sendmsg + mov ebx, 0000FFh + call writemsg + + + jmp wait_event + + +; +; Есть принятые данные +; + read_socket: + pushf + pushad + ;write_debug 'Some data in socket' + ; + ; Проверяем, не был ли получен заголовок отдельно от данных + ; в предыдущем цикле + ; + cmp [hrf], 1 + jz rs_head_recived + + + mov eax, 53 + mov ebx, 2 + mov ecx, [socket] + int 40h + cmp eax, 6 ; Flap head size + jc r_end + ; + ; Принимаем заголовок + ; + xor edx, edx + + ;mov ecx, [socket] + rs_loop: + mov eax, 53 + mov ebx, 3 + + int 40h + + mov [mbuff+edx], bl + inc edx + cmp edx, 6 + + jnz rs_loop + ; + ; Заполняем заголовок + ; + ;xor eax, eax + + ; + ; Заголовок принят! + ; + mov [hrf], 1 + + mov bl, [mbuff] + mov [rflap.bId], bl + + mov bl, [mbuff+1] + mov [rflap.bCh], bl + + mov bh, [mbuff+2] + mov bl, [mbuff+3] + mov [rflap.wSn], bx + + mov bh, [mbuff+4] + mov bl, [mbuff+5] + mov [rflap.wDs], bx + + ; + ; Принимаем данные + ; + ;xor edx, edx + cmp [rflap.bId], 2Ah + jnz rs_flap_error + ; + ; Проверяем, получены ли данные + ; + rs_head_recived: + + mov eax, 53 + mov ebx, 2 + ;mov ecx, [socket] + int 40h + cmp ax, [rflap.wDs] ; Размер данных + jc r_end + ; + ; + mov ax, [rflap.wDs] + ; + ; Проверяем размер данных + ; + cmp ax, MBUFF_SIZE+1 + jnc rs_big_flap + + xor esi, esi + mov esi, eax + xor edx, edx + + ;mov ecx, [socket] + + rs_data_loop: + cmp edx, esi + jz rs_data_end + + mov eax, 53 + mov ebx, 3 + int 40h + mov [mbuff+edx], bl + inc edx + jmp rs_data_loop + + ; + ; Данные приняты + ; + rs_data_end: + mov [hrf], 0 + write_debug 'Some data recived' + ; + ; + ; + cmp [login], 0 + jz rs_login + call main_loop + jmp r_end + + + rs_login: + call srv_login + ;write_debug 'Exited srv_login' + jmp r_end + + rs_flap_error: + write_debug 'Invalid Flap' + ; + ; FLAP.id неверный. нужно закрыть сокет + ; + + mov ecx, [socket] + ;call closesocket + jmp r_end + + ; + ; Слишком большой пакет! + ; + rs_big_flap: + + write_debug 'Too BIG FLAP Recived' + mov [hrf], 0 + + mov ecx, [socket] + mov ax, [rflap.wDs] + xor esi, esi + mov esi, eax + xor edx, edx + + rs_data_loop2: + cmp edx, esi + jz r_end + + mov eax, 53 + mov ebx, 3 + int 40h + ;mov [mbuff+edx], bl + inc edx + jmp rs_data_loop2 + + + + + + r_end: + + popad + popf + jmp wait_event + +; Соединение с сервером, возвращает в eax - хэндл сокета +; передаем в еах IP адрес сервера +; в ebx - порт + srv_connect: + push ecx + push edx + push esi + push edi + push ebx + + mov esi, eax ; IP - в esi + ; find free port + mov ecx, 1000 ; Определяем локальный порт, начинаем с 1000 + + getlp: + inc ecx + push ecx + mov eax, 53 + mov ebx, 9 + int 0x40 + pop ecx + cmp eax, 0 ; этот локальный порт используется? + jz getlp ; да - продолжаем перебирать + ;OK ecx = port number + ;Open Socket + mov eax, 53 + mov ebx, 5 + xor edx, edx + ;mov dx, ICQ_PORT + pop edx + ;mov esi,ICQ_IP + mov edi, 1;SOCKET_ACTIVE + + int 040h + ; + mov [socket], eax + ; + ; Ждем установки соедиения + mov ecx, eax + srv_loop: + + mov eax, 53 + mov ebx, 6 + int 40h + cmp eax, TCB_ESTABLISHED + jz fin + cmp eax, 11 + jae @f + ; + mov eax, 5 + mov ebx, 50 + int 40h + jmp srv_loop + + + + + ;cmp eax,-1 + ;jnz fin + ;delay 100 + write_debug 'CONNECTION FAILED' ;Подключение не удалось + jmp @f + ;connrcted: + ;CONNECTED + + fin: + write_debug 'Connected!!!!' + @@: + pop edi + pop esi + pop edx + pop ecx + ;pop ebx + ret + +; +; --> ecx socket handle +; + buff db 1024 dup 0 + lbuff db 8 dup 0 ; Для 1 пакета от сервера + srv_login: + pushf + push eax + push ebx + ;push ecx + push edx + + ; + ; Определяем тип полученных данных + ; + movzx eax, [rflap.bCh] + cmp eax, 01 + jz s_new_connection + cmp eax, 04 + jz s_cookie ; cookie + jmp l_flap_err + + s_new_connection: + ; + ; Проверяем полученный пакет + ; + movzx eax, [rflap.wDs] + cmp eax, 4 + jnz l_len_err + mov eax, dword [mbuff] + cmp eax, 01000000h ; 00 00 00 01 + jnz l_data_err + ; + ;Формируем пакет для соединения + ; + ;mov [flap.bId], FLAP_ID + mov [flap.bCh], NEW_CONNECTION + + mov eax, 26 + mov ebx, 9 + int 40h + mov [seq], ax + + mov [flap.wSn], ax ; Sequence number + ;mov [buff],0 + ;mov [buff+1],0 + ;mov [buff+2],0 + mov dword [buff], 0x01000000 ;login Protokol version 00 00 00 01 + ;mov[buff+4],0 + mov word [buff+4], 0x0100; TLV.TYPE = UIN 00 01 + + mov eax, UIN + call strlen + mov [buff+6], ah + mov [buff+7], al ; Length of UIN + mov edx, eax + add edx, 7 ; в edx длина заполненного буфера + + mov ecx, eax ;Длина строки + + mov eax, UIN + lea ebx, [buff+8] ; + размер данных в буфере + 1 + + call strcpy + + + mov eax, PASS + call roast + + mov [buff+edx+2], 2 ; TLV.TYPE - rosted password + call strlen + mov word [buff+edx+4], ax ; Length of pass + + add edx, 4 + mov ebx, buff + add ebx, edx ; назначение + add edx, eax ; Сохраняем в EDX длину заполненного буфнра + mov ecx, eax ; Длина строки + mov eax, PASS ; Источник + inc ebx + call strcpy + + mov [buff+edx+2], 3 ; TLV.TYPE - client id string + mov eax, ID_STRING + call strlen + mov word [buff+edx+4], ax + + add edx, 4 + mov ecx, eax + mov ebx, buff + add ebx, edx + add edx, eax + inc ebx + mov eax, ID_STRING + call strcpy + + mov [buff+edx+2], 016h ; TLV.TYPE - Client id + mov [buff+edx+4], 2 + mov word [buff+edx+6], ID_NUM + add edx, 6 + + mov [buff+edx+2], 017h ; Client major version + mov [buff+edx+4], 2 + mov [buff+edx+6], MAJOR + add edx, 6 + + mov [buff+edx+2], 018h ; Client minor version + mov [buff+edx+4], 2 + mov [buff+edx+6], MINOR + add edx, 6 + + mov [buff+edx+2], 019h ; Client lesser version + mov [buff+edx+4], 2 + mov [buff+edx+6], LESSER + add edx, 6 + + mov [buff+edx+2], 01Ah ; Client build number + mov [buff+edx+4], 2 + mov word [buff+edx+6], BUILD + add edx, 6 + + mov [buff+edx+2], 014h ; Client distribution number + mov [buff+edx+4], 4 + mov [buff+edx+8], DISTR + add edx, 8 + + mov [buff+edx+2], 0Fh ; Client language + mov eax, CL_LANG + call strlen + mov word [buff+edx+4], ax + add edx, 4 + mov ecx, eax + mov ebx, buff + add ebx, edx + inc ebx + add edx, eax + mov eax, CL_LANG + call strcpy + + mov [buff+edx+2], 0Fh ; Client language + mov eax, CL_COUNTRY + call strlen + mov word [buff+edx+4], ax + add edx, 4 + mov ecx, eax + mov ebx, buff + add ebx, edx + inc ebx + add edx, eax + mov eax, CL_COUNTRY + call strcpy + + ;write_debug 'Connect attemption' + ; mov eax, ICQ_IP + ; call srv_connect + ; cmp eax, -1 ; Подключение не удалось + ; jz l_fin + + ; mov ecx, eax + ; mov eax, rflap + ; mov ebx, lbuff + ; call recvflap + + ; cmp eax, -1 + ; jz l_flap_err + ; cmp [rflap.bCh], 01 ; AUTH channel + ; jnz l_ch_err + ; cmp eax, 4 + ; jnz l_len_err + ; cmp dword [lbuff+3], dword 1 + ; jnz l_data_err + + mov ecx, [socket] + inc dx + mov [flap.wDs], dx ; Data size + mov eax, flap + mov ebx, buff + call sendflap + cmp eax, 0 + jnz l_fin ; Неуспех + jmp l_end + + + s_cookie: + ;mov eax, rflap + ;mov ebx, buff + ;call recvflap + ;cmp eax, -1 + ;jz l_flap_err + ;cmp [rflap.bCh], 4 + ;jnz l_ch_err + + ;write_debug 'UIN' + xor ebx, ebx + + uin_loop: + xor eax, eax + mov ax, word [mbuff+ebx] + cmp ax, 0100h ; 00 01 TLV.Type UIN + jz l_uin_ok ; Теперь сервер передает еще данные при соединении, а потом опять + add ebx, 5 ; тот же TLV 1 + cmp ebx, 5 + ja l_tlvt_err + jmp uin_loop + + + + + + l_uin_ok: + mov eax, ebx + xor ebx, ebx + mov bl, [mbuff+eax+3] ; + mov bh, [mbuff+eax+2] ; Длина данных + ; + ; UIN Пока не проверяется + ; + + + lea ebx, [ebx+eax+4] + mov ax, word [mbuff+ebx] + cmp ax, 0500h ; 00 05 Bos address + jz l_all_ok + cmp ax, 0400h ; UIN incorrect + jz l_uin_err + cmp ax, 0800h + jz l_pass_err + jmp l_tlvt_err + ; + ; если неверный UIN/ пароль, получаем TLV.TYPE 4/8 + ; + + l_all_ok: + xor ecx, ecx + mov cl, [mbuff+ebx+3] ;length + mov ch, [mbuff+ebx+2] ; + + lea eax, [mbuff+ebx+4] + push ebx + mov ebx, bos_address + call strcpy + pop ebx + add ebx, ecx + lea ebx, [ebx+4] ; Размер заголовка + ; + ; cookie + ; + ;write_debug 'Login Cookie' + + xor eax, eax + mov ax, word [mbuff+ebx] + cmp ax, 0600h ; TLV.Type cookie + jnz l_tlvt_err + mov cl, [mbuff+ebx+3] ; + mov ch, [mbuff+ebx+2] ; Length + mov [cookie_len], cx + lea eax, [mbuff+ebx+4] + push ebx + mov ebx, srv_cookie + call strcpy + pop ebx + + ; + ; Соединяемся с BOS + ; + ;call srv_disconnect + mov ecx, [socket] + ;write_debug 'Closing socket' + ;call closesocket + ; + ; + ;mov eax, 53 + ;mov ebx, 8 + ;int 40h + + + + + mov eax, bos_address + call ip_parser + + call htonl + data_debug 'BOS Address: ', eax + data_debug 'BOS Port: ', ebx + mov [bos_ip], eax + mov [bos_port], ebx + call srv_connect + mov [login], 1 ; Соединение с основным сервером установлено + ;mov [socket], eax + + + + jmp l_end + ; + ; + ; + l_pass_err: + write_debug 'PASSWORD INVALID' + jmp l_fin + + l_uin_err: + write_debug 'UIN INVALID' + jmp l_fin + + l_data_err: + write_debug 'LOGIN DATA MISMATCH' + jmp l_fin + + l_len_err: + write_debug 'RECIVED DATA LENGTH MISMATCH' + jmp l_fin + + l_tlvt_err: + write_debug 'TLV TYPE MISMATCH' + jmp l_fin + + l_ch_err: + write_debug 'FLAP CHANNEL MISMATCH' + jmp l_fin + + l_flap_err: + write_debug 'FLAP ID MISMATCH / RECIVE ERROR' + + l_fin: + + ; + ; Необходимо закрыть сокет + ; + ;call srv_disconnect + ;call closesocket + l_end: + pop edx + ;pop ecx + pop ebx + pop eax + popf + ret + +; +; Length of string +; input eax = offset string +; output eax = strlen +; + strlen: + push ebx + push ecx + pushf + xor ebx, ebx + xor ecx, ecx + + loop_s: + mov cl, [eax+ebx] + cmp ecx,0 + jz nl + inc ebx + jmp loop_s + + nl: + mov eax, ebx + popf + pop ecx + pop ebx + ret + +; +; Roasting password +; EAX = offset password +; + + roast: + pushf + push ecx + push ebx + + xor ecx, ecx + xor ebx, ebx + + loop_r: + mov bl, [eax+ecx] ;Символ из массива пароля + cmp bl, 0 ;Конец строки + jz r_fin + + xor bl, [ROASTING_ARRAY+ecx] + mov [eax+ecx], bl + inc ecx + jmp loop_r + + r_fin: + pop ebx + pop ecx + popf + ret + + +; +;Copy string of bytes +;В EAX = адрес исходной строки +;В EBX = адрес назначения +;В ECX = длина строки +; + strcpy: + pushf + push esi + push edi + push ecx + + cld ;Обрабатываем строку от начала к концу + mov esi, eax + mov edi, ebx + + rep movsb + + pop ecx + pop edi + pop esi + popf + ret + + +; +; Заполняет буфер, по адресу в ebx +; данными, по адресу eax, в +; cx - Тип TLV +; dx - длина данных +; +; + + tlvstr: + ;pushf + push edx + push ecx + push ebx + + mov [ebx], ch ; Type + mov [ebx+1], cl + + mov [ebx+2], dh ; Length + mov [ebx+3], dl + + lea ebx, [ebx+4] + ; EBX = offset of destination + mov ecx, edx + + call strcpy + + pop ebx + pop ecx + pop edx + ;popf + ret + +; +; eax - указатель на FLAP_head +; ebx - указатель на массив, заполненный данными +; ecx - хендл сокета +; +; В eax возвращает результат записи в сокет +; + sendflap: + pushf + push edx + ;push ecx + push esi + push ebx + push ecx + + xor edx, edx + + mov dl, [eax] ; ID byte + mov [sbuff], dl + + mov dl, [eax+1] ; FLAP channel + mov [sbuff+1], dl + + mov dl, [eax+2] ; FLAP datagramm seq number + mov [sbuff+3], dl ; меняем местами байты для передачи по сети + mov dl, [eax+3] + mov [sbuff+2], dl + + mov dl, [eax+4] ; FLAP data size + mov [sbuff+5], dl + mov dl, [eax+5] + mov [sbuff+4], dl + mov dx, word [eax+4] + + xchg ecx, edx ; ecx - size edx - handle + mov eax, ebx ; data + mov ebx, sbuff ; dest + add ebx, 6 ; + header size + call strcpy + + xchg ecx, edx ; ecx - handle, edx - data size + + s_wait: + mov eax, 53 ; Проверяем состояние сокета. Если соедиение + mov ebx, 6 ; установлено - посылаем буфер, если сокет закрыт, уходим + int 40h + cmp eax, TCB_ESTABLISHED ; установлено + jz s_est + cmp eax, TCB_CLOSED + jz s_fin + cmp eax, 12 ; У меня такое было, когда соединение устанавливалось с пустотой :-) + jnc s_fin ; + + + mov eax, 5 + mov ebx, 1 + int 40h ; Ждем + jmp s_wait + + + s_est: + mov eax, 53 + mov ebx, 7 ; писать в сокет + ;xchg ecx, edx ; ecx - handle, edx - data length + add edx, 6 ; + size of header + mov esi, sbuff ; data + int 40h + + s_fin: + pop ecx + pop ebx + pop esi + ;pop ecx + pop edx + popf + ret + +; +; Принимает пакет из сокета +; eax - указатель на FLAP_head +; ebx - указатель на массив +; ecx - хендл сокета +; Возвращает в eax количество принятых байт в массиве +; +; recvflap: +; pushf +; +; ;push eax +; push ebx +; push esi +; push edi +; push edx +; mov esi, eax +; mov edi, ebx +; +; r_fail: +; mov eax, 53 ; Опрашивааем сокет +; mov ebx, 2 ; в eax количество полученных байт +; int 40h ; +; cmp eax, 6 ; буфер не пустой +; jnc r_ok +; +; mov eax, 53 ; Получаем состояние сокета +; mov ebx, 6 ; +; int 40h ; +; +; cmp eax, TCB_CLOSED ; закрыт - уходим +; jz r_err +; +; +; ;mov eax, 5 ; ждем +; ;mov ebx, 1 +; ;int 40h +; ; уходим +; +; ;jmp r_fail +; jmp rf_fin +; +; r_ok: ; В буфере данные +; +; mov eax, 53 +; mov ebx, 3 +; int 40h +; mov [esi], bl ; flap.bId +; cmp bl, FLAP_ID +; jnz r_err +; +; mov eax, 53 +; mov ebx, 3 +; int 40h +; mov [esi+1], bl ; flap.bCh +; +; mov eax, 53 +; mov ebx, 3 +; int 40h +; mov [esi+3], bl ; flap.wSn старший байт +; +; mov eax, 53 +; mov ebx, 3 +; int 40h +; mov [esi+2], bl ; flap.wSn младший байт +; +; mov eax, 53 +; mov ebx, 3 +; int 40h +; mov [esi+5], bl ; flap.wDs старший байт +; +; mov eax, 53 +; mov ebx, 3 +; int 40h +; mov [esi+4], bl ; flap.wDs младший байт +; +; r_check: +; mov eax, 53 ; Проверяем число полученных байт +; mov eax, 2 +; int 40h +; +; xor ebx, ebx +; mov bx, word [esi+4] ; flap.wDs +; cmp eax, ebx +; jnc r_drr ;>= +; +; mov eax, 68 ; wait +; mov ebx, 1 +; int 40h +; jmp r_check +; +; r_drr: ; ready for data recive +; +; +; xor edx, edx +; mov dx, word [esi+4] ; flap.wDs +; xor esi, esi +; +; rf_loop: +; mov eax, 53 +; mov ebx, 3 +; int 40h +; mov [edi+esi], bl +; inc esi +; cmp esi, edx +; jnz rf_loop +; mov eax, edx +; jmp rf_fin +; +; r_err: +; ;pop ebx +; ;pop eax +; mov eax, -1 +; jmp rf_fin +; +; +; rf_fin: +; pop edx +; pop edi +; pop esi +; pop ebx +; ;pop eax +; popf +; ret + +; +; eax - указатель на буфер +; ebx - значение, которым необходимо затолнить. Используется только bl +; ecx - размер +; + + memset: + pushf + push edi + push eax + push ebx + push ecx + + cld + mov edi, eax + mov eax, ebx + rep stosb + + pop ecx + pop ebx + pop eax + pop edi + popf + ret + +; +; Парсим TLV +; <-- в eax адрес TLV +; <-- в ebx адрес буфера, который нужно заполнить +; --> в ebx длина полученных данных +; --> в eax тип TLV +; + + tlvpar: + pushf + ;push esi + ;push edi + push ecx + xor ecx, ecx + + mov cl, [eax+3] ;TLV.Length + mov ch, [eax+2] + call strcpy + + xor eax, eax + mov al, [ebx+1] ;TLV.Type + mov ah, [ebx] + mov ebx, ecx + + + pop ecx + ;pop edi + ;pop esi + popf + ret + +; +; <-- ECX - хендл сокета, который нужно закрыть +; --> ECX - Результат (Ненадежно) +; + closesocket: + push eax + push ebx + + mov eax, 53 + mov ebx, 8 + int 40h + + mov ecx, eax + + pop ebx + pop eax + ret + +; +; ecx <-- хендл сокета +; +; + + srv_disconnect: + pushf + push eax + push ebx + mov [flap.bId], FLAP_ID + mov [flap.bCh], 4 ;Disconnect + xor eax, eax + mov ax, [seq] + mov [flap.wSn], ax + mov [flap.wDs], 0 + mov eax, flap + mov ebx, buff + call sendflap + + + pop ebx + pop eax + popf + ret + +; +; <-- eax [bos_address] +; --> eax = IP ADDRESS +; --> ebx = port number +; +par_buff db 9 dup 0 + + ip_parser: + pushf + push ecx + push edx + push esi + push edi + + xor ecx, ecx + ;xor eax, eax + xor ebx, ebx + xor edx, edx + xor esi, esi + xor edi, edi + + ip_loop: + xor eax, eax + ;xor edx, edx + mov al, [bos_address+ecx] + cmp al, '.' + jz ip_dot + + cmp al, 0 + jz ip_end_str + + cmp al, ':' + jz ip_colon + + ;sub al, 30h + ;cmp al, 9 + ;ja ip_err ; Не цифра + + mov [par_buff+edx], al + inc ecx + inc edx + jmp ip_loop + + ip_dot: + ;xor eax, eax + mov [par_buff+edx], 0 ; Конец строки + mov eax, par_buff + call ascitoint + + ;data_debug 'Debug eax: ', eax + + cmp ecx, 0 ; Не может начинаться с точки + jz ip_err + shl esi, 8 ; Сдвигаем предыдущий байт + add esi, eax + inc ecx + xor edx, edx ; Счетчик буфера = 0 + jmp ip_loop + + + ip_colon: ; : В строке адреса + inc edi ; Было : + jmp ip_dot + + ip_end_str: + cmp edi, 1 + jz @f + ; : Не было + mov [par_buff+edx], 0 ; Конец строки + mov eax, par_buff + call ascitoint + shl esi, 8 ; Сдвигаем предыдущий байт + add esi, eax + ;mov eax, esi ; IP в 16 ричной форме + ;xor ebx, ebx ; Номера порта нет + jmp ip_end + + @@: ; Было : + mov [par_buff+edx], 0 + mov eax, par_buff + call ascitoint + mov ebx, eax + jmp ip_end + + ip_err: + xor esi, esi + + ip_end: + mov eax, esi + + pop edi + pop esi + pop edx + pop ecx + popf + ret + +; +; <-- eax указатель на asci +; --> eax int +; + ascitoint: + pushf + push ebx + push ecx + push edx + push esi + push edi + + xor ebx, ebx + xor ecx, ecx + xor edx, edx + ;xor esi, esi + xor edi, edi + + ati_loop: + mov bl, [eax+ecx] + cmp bl, 0 ; Конец строки + jz ati_str_end + cmp bl, 39h + ja ati_err ; Не цифра + cmp bl, 30h + jb ati_err + + inc ecx + jmp ati_loop + + ati_str_end: ; В ecx длина строки + ;dec ecx ; Установим на последний символ + add eax, ecx ; Указатель на строку + Длина строки + dec eax + + ati_loop2: + cmp edx, ecx + jz ati_all + push eax + sub eax, edx ; Вычесть счетчик + movzx ebx, byte [eax] ; В bl символ + ;pop eax + sub bl, 30h ; Вычисляем 10тичную цифру + + ;push eax + mov eax, ebx ; В eax - цифра + mov ebx, 10 ; Множитель + + xor esi, esi + + ati_mul: + + cmp esi, edx ; Умножаем на 10 n раз + jz ati_mul_end + ;push eax + ;mov eax, ebx + imul eax, ebx + ;mov ebx, eax + ;pop eax + inc esi + jmp ati_mul + + + ati_mul_end: + mov ebx, eax ; В ebx вычисленное число + pop eax + + add edi, ebx + inc edx + jmp ati_loop2 + + ati_all: + mov eax, edi + jmp ati_end + + ati_err: + + ;ati_str_end: + xor eax, eax + + ati_end: + pop edi + pop esi + pop edx + pop ecx + pop ebx + popf + ret + +; +; +; <-- ecx хендл сокета +; <-- eax указатель на структуру SNAC_head +; <-- ebx указатель на данные +; <-- edx размер данных +; --> eax результат записи в сокет +; + +snac_buff db 1024 dup 0 + + sendsnac: + pushf + push esi + push edi + push ebx + push edx + ;xor ebx, ebx + mov esi, ecx ; хендл сокета + mov edi, ebx ; Указатель на данные + + xor ebx, ebx + mov bl, [eax] ; + mov [snac_buff+1], bl ; Family ID + mov bl, [eax+1] ; Конвертируется в BigEndian + mov [snac_buff], bl ; + + mov bl, [eax+2] ; + mov [snac_buff+3], bl ; Subtype ID + mov bl, [eax+3] ; + mov [snac_buff+2], bl ; + + mov bl, [eax+4] ; + mov [snac_buff+5], bl ; + mov bl, [eax+5] ; Flags + mov [snac_buff+4], bl ; + + mov bl, [eax+6] ; + mov [snac_buff+9], bl ; + mov bl, [eax+7] ; + mov [snac_buff+8], bl ; + mov bl, [eax+8] ; Reqest ID + mov [snac_buff+7], bl ; + mov bl, [eax+9] ; + mov [snac_buff+6], bl ; + + lea ebx, [snac_buff+10] + + mov eax, edi ; Указатель на данные + ;add ebx, 10 ; + размер заголовка SNAC + mov ecx, edx ; размер данных + call strcpy + + + mov ecx, esi ; Хендл сокета + mov [flap.bId], FLAP_ID + mov [flap.bCh], 2 ; Канал для посылки SNAC + xor ebx, ebx + inc [seq] ; seq Увеличивается на 1 при каждой посылке + mov bx, [seq] + mov [flap.wSn], bx + add edx, 10 ; размер данных + размер заголовка SNAC + mov [flap.wDs], dx + mov eax, flap + mov ebx, snac_buff + call sendflap + + pop edx + pop ebx + pop edi + pop esi + popf + ret + + + +; Обработка всех пактов, приходящих от сервера +; ECX <-- Хендл сокета +; +; +; +; +; + main_loop: + pushf + ;push eax + ;push ebx + ;push edx + pushad + + mov ecx, [socket] + ; + ; ждем пакет + ; + ;m_loop: + ;mov eax, 53 + ;mov ebx, 2 + ;int 40h + ;cmp eax, 6 ; размер заголоака FLAP + ;jnc recived ; >= + ; + ; Уходим + ; + ;jmp m_fin + ;mov eax, 5 + ;mov ebx, 5 + ;int 40h + ;jmp m_loop + ; + ; есть пакет + ; + ;recived: + ;mov eax, rflap + ;mov ebx, rbuff + ;call recvflap + ; + ; Определяем тип принятого FLAP + ; + xor ebx, ebx + mov bl, [rflap.bCh] + cmp bl, 1 ; Установка соединения + jz m_login + cmp bl, 2 + jz m_snac ; Получен SNAC + cmp bl, 3 + jz m_flap_err ; FLAP-level error + cmp bl, 4 + jz m_close_conn ; Закрытие соединения + cmp bl, 5 + jz m_keep_alive ; + ; + ; Обработка рассоединения + ; + m_close_conn: + write_debug 'Another Computer Use YOUR UIN!' + call srv_disconnect + call closesocket + jmp m_fin + ; + ; обработка соединения + ; + m_login: + ; + ; проверяем версию протокола + ; + xor eax, eax + mov al, [mbuff+3] + cmp eax, 1 + jnz m_login_other ; Не подходит + + + ; + ; генерируем случайный seq + ; Для этого берем время, прошедшее с момента запуска системы + ; + mov eax, 26 + mov ebx, 9 + int 40h + mov [seq], ax + ; + ; Отдаем серверу cookie + ; + mov [flap.bCh], 1 + mov [flap.wSn], ax + xor eax, eax + mov ax, [cookie_len] + add eax, 8 ; TLV len + protocol version len + mov [flap.wDs], ax + mov dword [buff], 01000000h ; 00 00 00 01 Номер протокола + mov word [buff+4], 0600h ; 00 06 TLV.Type + + mov ax, [cookie_len] + mov [buff+6], ah ; + mov [buff+7], al ; TLV.Length + + mov edx, ecx ; edx <-- socket handle + + mov ecx, eax ; ecx <-- cookie len + mov eax, srv_cookie ; Src + lea ebx, [buff+8] + call strcpy + + mov ecx, edx ; ecx <-- socket handle + mov eax, flap + mov ebx, buff + call sendflap + jmp m_fin + + m_login_other: + jmp m_fin + + ; + ; Как обработать ошибку, я не знаю + ; + m_flap_err: + jmp m_fin + + ; + ; Пока не обрабатывается + ; + m_keep_alive: + jmp m_fin + + + ; + ; Получен SNAC + ; Распознаем его тип + ; + m_snac: + mov eax, rsnac + mov ebx, mbuff + call snacpar + xor ebx, ebx + xor edx, edx + mov bx, [rsnac.wFid] + mov dx, [rsnac.wSid] + + cmp bx, 1 + jz m_snac_1 ;Generic service controls + cmp bx, 2 + jz m_snac_2 ;Location services + cmp bx, 3 + jz m_snac_3 ;Buddy List management service + cmp bx, 4 + jz m_snac_4 ;ICBM (messages) service + cmp bx, 9 + jz m_snac_9 ;Privacy management service + cmp bx, 015h + jz m_snac_15 ;ICQ specific extensions service + cmp bx, 013h + jz m_snac_13 ;Server Side Information (SSI) service + + jmp m_other_snac + ; + ; FAMILY 1 + ; + m_snac_1: + cmp dx, 7 + jz m_snac_1_7 + cmp dx, 3 + jz m_snac_1_3 + cmp dx, 018h + jz m_snac_1_18 + cmp dx, 01Fh + jz m_snac_1_f + cmp dx, 13h + jz m_snac_13 + cmp dx, 1 + jz m_snac_1_1 + jmp m_snac_1_other + ; + ; Rate limits information response + ; + m_snac_1_7: ; Отвечаем + mov [ssnac.wFid], 1 ; Family + mov [ssnac.wSid], 8 ; Subtype + mov [ssnac.dRi], 8 + mov word [buff], 0100h ; 0001 + mov word [buff+2], 0200h ; 0002 + mov word [buff+4], 0300h ; 0003 + mov word [buff+6], 0400h ; 0004 + mov word [buff+8], 0500h ; 0005 + mov eax, ssnac + mov ebx, buff + mov edx, 10 ; Размер данных + call sendsnac + ; + ; Client ask server location service limitations + ; + mov [ssnac.wFid], 2 ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 2 + mov eax, ssnac + mov ebx, buff + xor edx, edx + call sendsnac + + jmp m_fin + + ; + ; Server supported snac families list + ; + m_snac_1_3: + ; + ; Server sends supported services list + ; + + ; + ; SNAC(01,17) + ; Client ask for services version numbers + ; + mov [ssnac.wFid], 1 ; Family + mov [ssnac.wSid], 17h ; Subtype + mov [ssnac.dRi], 17h + ; + ; Список сервисов, которые нам нужны + ; + ; xx xx word family number #1 + ; xx xx word family version + ; ... ... ... + ; + + ; + ; Поправил из дампа &RQ + ; + mov word [buff], 0100h ; 0001 + mov word [buff+2], 0300h ; 0003 + + mov word [buff+4], 1300h ; 0013 + mov word [buff+6], 0200h ; 0002 + + mov word [buff+8], 0200h ; 0002 + mov word [buff+10], 0100h ; 0001 + + mov word [buff+12], 0300h ; 0002 + mov word [buff+14], 0100h ; 0001 + + mov word [buff+16], 1500h ; 0015 + mov word [buff+18], 0100h ; 0001 + + mov word [buff+20], 0400h ; 0004 + mov word [buff+22], 0100h ; 0001 + + mov word [buff+24], 0600h ; 0006 + mov word [buff+26], 0100h ; 0001 + + mov word [buff+28], 0900h ; 0009 + mov word [buff+30], 0100h ; 0001 + + mov word [buff+32], 1300h ; 0013 + mov word [buff+34], 0400h ; 0004 + + mov word [buff+36], 1500h ; 0015 + mov word [buff+38], 0400h ; 0004 + + mov word [buff+40], 1000h ; 0010 + mov word [buff+42], 0100h ; 0001 + + + + mov eax, ssnac + mov ebx, buff + mov edx, 44 + call sendsnac + + jmp m_fin + + + ; + ; Server services versions + ; + m_snac_1_18: + ; + ; Обработки пока нет + ; + + ; + ; Client ask server for rate limits info + ; SNAC(01,06) + ; + mov [ssnac.wFid], 1 ; Family + mov [ssnac.wSid], 6 ; Subtype + mov [ssnac.dRi], 6 + mov eax, ssnac + mov ebx, buff + xor edx, edx + call sendsnac + + + + jmp m_fin + + ; + ; Requested online info response + ; + m_snac_1_f: + ; + ;Тут должна быть наша информация, пока обработки нет + ; + + + jmp m_fin + + ; + ; Message of the day (MOTD) + ; + m_snac_1_13: + ; + ; Нечего обрабатывать :-)) + ; + jmp m_fin + + ; + ; Сообщение об ошибке + ; + + m_snac_1_1: + xor eax, eax + mov ax, word [mbuff+10] + call ntohs + data_debug 'SERVER SEND ERROR #', eax + + + jmp m_fin + + + m_snac_1_other: + data_debug 'Unknown SNAC Family 1 recived, type ', edx + jmp m_fin + + + + ; + ; Family 2 + ; + m_snac_2: + cmp dx, 3 + jz m_snac_2_3 + jmp m_snac_2_other + ; + ; Server replies via location service limitations + ; + m_snac_2_3: + ; + ; Обработки пока нет + ; + + ; + ; посылаем capabilities / profile + ; + mov [ssnac.wFid], 2 ; Family + mov [ssnac.wSid], 4 ; Subtype + mov [ssnac.dRi], 4 + + ;mov eax, CAPABILITIES + ;mov ebx, buff + ;push ecx + ;mov ecx, 5 ; TLV.Type(0x05) - CLSID values + ;mov edx, C_LEN + ;call tlvstr + ;pop ecx + mov word [buff], 0500h ; 00 05 + mov eax, C_LEN + call htons + mov word [buff+2], ax + + + + push ecx + + mov eax, CAPABILITIES + lea ebx, [buff+4] + mov ecx, C_LEN + call strcpy + + pop ecx + + + mov eax, ssnac + mov ebx, buff + mov edx, C_LEN+4 ; Длина данных+размер заголовка TLV + call sendsnac + + ; + ; запрашиваем server BLM service limitations + ; + mov [ssnac.wFid], 3 ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 2 + mov eax, ssnac + mov ebx, buff + xor edx, edx + call sendsnac + + + jmp m_fin + + m_snac_2_other: + write_debug 'Unknown SNAC Family 2 Recived' + jmp m_fin + + + + ; + ; FAMILY 3 + ; + m_snac_3: + cmp dx, 3 + jz m_snac_3_3 + cmp dx, 0Bh + jz m_snac_3_b + cmp dx, 0Ch + jz m_snac_3_c + jmp m_snac_3_other + + ; + ; Server replies via BLM service limitations + ; + m_snac_3_3: + ; + ; Обработки пока нет + ; + + ; + ; Client ask server for ICBM service parameters + ; + mov [ssnac.wFid], 4 ; Family + mov [ssnac.wSid], 4 ; Subtype + mov [ssnac.dRi], 4 ; request-id + mov eax, ssnac + mov ebx, buff + xor edx, edx + call sendsnac + + + + jmp m_fin + + ; + ; User online notification + ; + m_snac_3_b: + ; + ; Из всей информации пока нужен только статус + ; + xor edx, edx ; Счетчик + xor ecx, ecx + xor eax, eax + cld ; В направлении увеличения адресов + + dec edx + m_snac_3_b_loop: + inc edx + cmp edx, UINS + jnc m_snac_3_b_end ;>= + + mov cl, [mbuff+10] ; Длина УИН + mov eax, ecx + mov edi, UIN_LEN + imul edi ,edx + lea edi, [uins+edi] + lea esi, [mbuff+11] + repe cmpsb + + jnz m_snac_3_b_loop + ; + ; UIN Определен + ; + + lea ecx, [eax+10+11] ; +sizeof SNAC_head + offset #2 TLV + mov ax, word [mbuff+ecx] ;#2 TLV.Type + cmp ax, 0C00h ;dc info (optional) + jz m_snac_3_b_dc + cmp ax, 0A00h ;external ip address + jz m_snac_3_b_extip + jmp m_snac_3_b_bad_tlv + + + m_snac_3_b_dc: + ; + ; Пропускаем этот TLV + ; + lea ecx, [ecx+41] + m_snac_3_b_extip: + ; + ; И этот :-) + lea ecx, [ecx+8] + mov ax, word [mbuff+ecx] + cmp ax, 0600h ;TLV.Type(0x0A) - external ip address + jz m_snac_3_b_status + jmp m_snac_3_b_bad_tlv + + m_snac_3_b_status: + ; + ; наконец-то статус 8-) + ; + mov eax, dword [mbuff+ecx+4] + call ntohl + ;mov ebx, 4 + ;imul ebx, edx + ;mov [stats+ebx], eax + mov ecx, eax + mov ebx, NAME_LEN + imul ebx, edx + lea ebx, [names+ebx] + mov eax, edx + call loadbb + jmp m_fin + + + m_snac_3_b_bad_tlv: + write_debug 'TLV Type Mismatch in SNAC(3,b)' + jmp m_fin + + m_snac_3_b_end: + write_debug 'UIN not in local Contact List' + jmp m_fin + + + + m_snac_3_c: + ; + ; User offline notification + ; + xor edx, edx + xor ecx, ecx + + dec edx + m_snac_3_c_loop: + inc edx + cmp edx, UINS + jnc m_snac_3_b_end ;>= + + mov cl, [mbuff+10] ; Длина УИН + mov edi, UIN_LEN + imul edi ,edx + lea edi, [uins+edi] + lea esi, [mbuff+11] + repe cmpsb + jnz m_snac_3_c_loop + ; + ; UIN Определен + ; + ;mov eax, -1 + ;mov ebx, 4 + ;imul ebx, edx + ;mov [stats+ebx], eax + mov ecx, -1 + mov ebx, NAME_LEN + imul ebx, edx + lea ebx, [names+ebx] + mov eax, edx + call loadbb + jmp m_fin + + + + + + + m_snac_3_other: + write_debug 'Unknown SNAC Family 3 Recived' + jmp m_fin + + + ; + ; FAMILY 4 + ; + m_snac_4: + cmp dx, 5 + jz m_snac_4_5 + cmp dx, 7 + jz m_snac_4_7 + jmp m_snac_4_other + + ; + ; Server sends ICBM service parameters to client + ; + m_snac_4_5: + ; + ; Обработки пока нет + ; + + ; + ; Client change default ICBM parameters command + ; + mov [ssnac.wFid], 4 ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 2 ; request-id + + mov eax, ICBM_PARAMS + mov ebx, buff + push ecx + mov ecx, ICBMP_LEN + call strcpy + pop ecx + + mov eax, ssnac + mov ebx, buff + mov edx, ICBMP_LEN + call sendsnac + + ; + ; Client ask server PRM service limitations + ; + mov [ssnac.wFid], 9 ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 2 ; request-id + mov eax, ssnac + mov ebx, buff + xor edx, edx + call sendsnac + + + jmp m_fin + + ; + ; Message for client from server + ; + m_snac_4_7: + ; + ; Определяем тип сообщения по полю message channel + ; + xor eax, eax + mov ax, word [mbuff+10+8] ; +10 - размер SNAC + ; +8 смещение до message channel + cmp ax, 0100h ; 00 01 + jz m_snac_ch1 + cmp ax, 0200h + jz m_snac_ch2 + cmp ax, 0400h + jz m_snac_ch4 + jmp m_ch_other + ; + ; channel 1 plain text + ; + m_snac_ch1: + ; + ; Т.к в очередной раз описание протокола не совпадает с реальностью + ; разбираем все TLV по порядку + + mov eax, dword [mbuff+10] ; cookie + mov [msg_cookie1], eax + mov eax, dword [mbuff+10+4] + mov [msg_cookie2], eax ; Используются для потверждения приема сообщений + + mov al, [mbuff+10+10] ; Sender UIN length + mov [ui.bUinLength], al + + push ecx + movzx ecx, al + + lea eax, [mbuff+10+11] ; UIN string + lea ebx, [ui.bUin] ; Dest + call strcpy + + lea ecx, [ecx+10+15] ; первый TLV + + + m_snac_ch1_loop: + + movzx eax, word [mbuff+ecx] + cmp eax, 0100h ;TLV.Type(0x01) - user class + jz m_snac_ch1_1 + cmp eax, 0600h ;TLV.Type(0x06) - user status + jz m_snac_ch1_6 + cmp eax, 0800h ; Unknown type + jz m_snac_ch1_8 + cmp eax, 0500h ; Unknown type + jz m_snac_ch1_5 + cmp eax, 0F00h ; TLV.Type(0x0f) - user idle time + jz m_snac_ch1_f + cmp eax, 0300h ; TLV.Type(0x03) - account creation time + jz m_snac_ch1_3 + cmp eax, 0400h ; TLV.Type(0x04) - automated response flag + jz m_snac_ch1_4 + cmp eax, 0200h ; TLV.Type(0x02) - message data + jz m_snac_ch1_mess + jmp m_snac_msg_tlv_err + + ; + ; Возможно, дополнительная ииформация будет обрабатываться + ; но пока нет + + m_snac_ch1_1: + movzx eax, word [mbuff+ecx+2] ; TLV.Length + call ntohs + lea ecx, [eax+ecx+4] + jmp m_snac_ch1_loop + + m_snac_ch1_6: + + mov eax, dword [mbuff+ecx+4] ; User status + call ntohl + mov [ui.dUserStatus], eax + + + movzx eax, word [mbuff+ecx+2] ; TLV.Length + call ntohs + lea ecx, [eax+ecx+4] + ; + ; + + + jmp m_snac_ch1_loop + + m_snac_ch1_8: + movzx eax, word [mbuff+ecx+2] ; TLV.Length + call ntohs + lea ecx, [eax+ecx+4] + jmp m_snac_ch1_loop + + m_snac_ch1_5: + movzx eax, word [mbuff+ecx+2] ; TLV.Length + call ntohs + lea ecx, [eax+ecx+4] + jmp m_snac_ch1_loop + + m_snac_ch1_f: + movzx eax, word [mbuff+ecx+2] ; TLV.Length + call ntohs + lea ecx, [eax+ecx+4] + jmp m_snac_ch1_loop + + m_snac_ch1_3: + movzx eax, word [mbuff+ecx+2] ; TLV.Length + call ntohs + lea ecx, [eax+ecx+4] + jmp m_snac_ch1_loop + + + m_snac_ch1_4: + ;movzx eax, word [buff+ecx+2] ; TLV.Length + lea ecx, [ecx+4] + jmp m_snac_ch1_loop + + + + m_snac_ch1_mess: + ; + ; + movzx eax, word [mbuff+ecx+4] ; + cmp eax, 0105h ; 05 fragment identifier (array of required capabilities) + jnz m_snac_ch1_fr_err ; 01 fragment version + + movzx eax, word [mbuff+ecx+6] ; Length + call ntohs + + lea ecx, [ecx+eax+8] ; Пропускаем byte array of required capabilities (1 - text) + + movzx eax, word [mbuff+ecx] ; fragment identifier (message text) + cmp eax, 0101h ; fragment version + jnz m_snac_ch1_fr_err + + movzx eax, word [mbuff+ecx+2] ; TLV Length + call ntohs + xchg eax, ecx + + lea eax, [eax+8] ; Начало текстового сообщения + lea ecx, [ecx-4] ; - sizeof Message charset number, Message charset subset + + push eax + push ecx + + ; + ; Выводим Message From UIN + ; + + mov eax, MESS + call strlen + mov ecx, eax + + mov eax, MESS + mov ebx, buff + call strcpy + + lea ebx, [ebx+ecx] + lea eax, [ui.bUin] + movzx ecx, byte [ui.bUinLength] + call strcpy + + mov [ebx+ecx], byte 0 + + mov eax, buff + xor ebx, ebx + + call writemsg + ; + ; Само сообщение + ; + + pop ecx + pop eax + lea eax, [mbuff+eax] + + mov ebx, buff + call strcpy + mov [ebx+ecx], byte 0 + + mov eax, buff + call win2dos + mov ebx, 00FF0000h + call writemsg + + ; + ; Подтверждаем прием + ; + + pop ecx + ; + ; Пока не реализовано, т.к. не могу найти клиент, который это использует :-) + ; + + jmp m_fin + + m_snac_msg_tlv_err: + write_debug 'TLV TYPE MISMATCH' + pop ecx + jmp m_fin + + m_snac_ch1_fr_err: + write_debug 'UNKNOWN FRAGMENT IDENTIFIER OR FRAGMENT VERSION' + + ;m_snac_ch1_end: + pop ecx + + jmp m_fin + + ; + ; Channel 2 message format (rtf messages, rendezvous) + ; + m_snac_ch2: + ; + ; отправим сообщение, что канал не поддерживается + ; нужны куки и уин + mov eax, dword [mbuff+10] + mov [msg_cookie1], eax + mov eax, dword [mbuff+10+4] + mov [msg_cookie2], eax + + mov al, [mbuff+10+10] ; Sender UIN length + mov [ui.bUinLength], al + + push ecx + movzx ecx, al + + lea eax, [mbuff+10+11] ; UIN string + lea ebx, [ui.bUin] ; Dest + call strcpy + + + mov [ssnac.wFid], 4 ; Family + mov [ssnac.wSid], 0Bh ; Subtype + mov [ssnac.dRi], 0Bh + + mov eax, [msg_cookie1] + mov dword [buff], eax + mov eax, [msg_cookie2] + mov dword [buff+4], eax + mov word [buff+8], 0200h ; Channel 2 + + mov al, [ui.bUinLength] + mov [buff+10], al + lea eax, [ui.bUin] + lea ebx, [buff+11] + call strcpy + lea ecx, [ecx+11] + + mov word [buff+ecx], 0100h ; reason code (1 - unsupported channel, 2 - busted payload, 3 - channel specific) + mov edx, ecx + + pop ecx + mov eax, ssnac + mov ebx, buff + call sendsnac + + + jmp m_fin + + ; + ; Channel 4 message format (typed old-style messages) + ; + m_snac_ch4: + + + + m_ch_other: + write_debug 'Unknown message channel' + + jmp m_fin + + + m_snac_4_other: + write_debug 'Unknown SNAC Family 4 recived' + jmp m_fin + + + + ; + ; FAMILY 9 + ; + m_snac_9: + cmp dx, 3 + jz m_snac_9_3 + jmp m_snac_9_other + + ; + ; Server sends PRM service limitations to client + ; + m_snac_9_3: + ; + ; Обработки пока нет + ; + + + ; Отключено, тк не поддерживается SIQ + ; + + ; + ; Client ask server for SSI service limitations + ; + ;mov [ssnac.wFid], 13h ; Family + ;mov [ssnac.wSid], 2 ; Subtype + ;mov [ssnac.dRi], 2 ; request-id + ;mov eax, ssnac + ;mov ebx, buff + ;xor edx, edx + ;call sendsnac + + ; + ; последняя стадия соединения + ; + + ; + ; Запрашиваем свою информацию + ; + mov [ssnac.wFid], 1 ; Family + mov [ssnac.wSid], 0Eh ; Subtype + mov [ssnac.dRi], 0Eh ; request-id + + mov eax, ssnac + mov ebx, buff + xor edx, edx ; TLV head len + call sendsnac + + + ; + ; Client sends its DC info and status to server + ; + mov [ssnac.wFid], 1 ; Family + mov [ssnac.wSid], 1Eh ; Subtype + mov [ssnac.dRi], 1Eh ; request-id + + mov [buff], 0 ; TLV type 06 + mov [buff+1], 6h ; + mov [buff+2], 0 ; TLV data length + mov [buff+3], 4 ; + ; + ; + mov ax, STATUS_DCDISABLED ; DC disabled + call htons + mov word [buff+4], ax + mov ax, STATUS_ONLINE + mov [status], ax + mov word [buff+6], ax + + mov eax, ssnac + mov ebx, buff + mov edx, 8 ; TLV head len+ data len + call sendsnac + + + ; + ; Выгружаем на сервер КЛ + ; + call uploadkl + + ; + ; Выгружаем инвизибл лист, пока пустой + ; + mov [ssnac.wFid], 9 ; Family + mov [ssnac.wSid], 7 ; Subtype + mov [ssnac.dRi], 7 + + mov eax, ssnac + mov ebx, buff + xor edx, edx + call sendsnac + + ; + ; В &RQ Есть пакет установки разрешений. я использую его без изменения + ; т.к. не знаю, что он содержит + ; + + mov [ssnac.wFid], 15 ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 2 + + mov word [buff], 0100h ; 00 01 encapsulated META_DATA + mov word [buff+2], 1000h ; 00 10 Len + mov word [buff+4], 000Eh ; LE Len + mov word [buff+10], 07D0h ; META_DATA_REQ + + + mov eax, UIN + call ascitoint + mov dword [buff+6], eax + + mov word [buff+12], 0102h ; request sequence number (incrementing) + mov word [buff+14], 0424h ; META_SET_PERMS_USERINFO + mov [buff+16], 1 ; authorization (1-required, 0-not required) + mov [buff+17], byte 0 ; webaware (0-no, 1-yes) + mov [buff+18], 1 ; dc_perms (0-any, 1-contact, 2-authorization) + mov [buff+19], 0 ;unknown + + mov eax, ssnac + mov ebx, buff + mov edx, 20 + + + ; + ; Client READY command + ; + mov [ssnac.wFid], 1 ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 2 ; request-id + + mov eax, FAMILY_ARR + mov ebx, buff + push ecx + mov ecx, FA_LEN + call strcpy + pop ecx + + mov eax, ssnac + mov ebx, buff + mov edx, FA_LEN + call sendsnac + + + ; + ; Запрашиваем offline сообщения + ; + mov [ssnac.wFid], 15h ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 2 ; request-id + + mov word [buff], 0100h ; TLV type 01 + mov word [buff+2], 0A00h ; 00 0a Длина + mov word [buff+4], 0008h ; 08 00 + mov eax, UIN + call ascitoint + mov dword [buff+6], eax + + mov [buff+10], 003Ch ; 3C 00 - Запрос на оффлайновые сообщения + mov [buff+12], 0002 ; 02 00 - request sequence number + + mov edx, 14 ; Общий размер данных в буфере + + mov eax, ssnac + mov ebx, buff + call sendsnac + + + + ; + ; Запрашиваем информацию всех UIN + ; + call getinfo + ; + ; завершено соединение + ; + mov [login], 2 + + jmp m_fin + + m_snac_9_other: + write_debug 'Unknown SNAC Family 9 Recived' + jmp m_fin + + + ; + ; FAMILY 13 + ; + m_snac_13: + cmp dx, 3 + jz m_snac_13_3 + cmp dx, 0fh + jz m_snac_13_F + + jmp m_snac_13_other + + ; + ; Server sends SSI service limitations to client + ; + m_snac_13_3: + ; + ; Обработки пока нет + ; + + ; + ; SNAC(13,05) Client check if its local SSI copy is up-to-date + ; + mov [ssnac.wFid], 13h ; Family + mov [ssnac.wSid], 5 ; Subtype + mov [ssnac.dRi], 5 ; request-id + mov eax, ssnac + ; 3D E7 48 17 + mov [buff], 03Dh ; + mov [buff+1], 0E7h ; modification date/time of client local SSI copy + mov [buff+2], 48h ; + mov [buff+3], 17h ; + ; 00 10 + mov [buff+4], 00 ; + mov [buff+5], 10h ; number of items in client local SSI copy + + mov ebx, buff + mov edx, 5 + call sendsnac + + jmp m_fin + + ; + ; Server tell client its local copy up-to-date + ; + m_snac_13_F: + ; + ; Обработки нет + ; + + ; + ; Client activates server SSI data + ; + mov [ssnac.wFid], 13h ; Family + mov [ssnac.wSid], 7 ; Subtype + mov [ssnac.dRi], 7 ; request-id + mov eax, ssnac + mov ebx, buff + xor edx, edx + call sendsnac + + ; + ; последняя стадия соединения + ; + + ; + ; Client sends its DC info and status to server + ; + mov [ssnac.wFid], 1 ; Family + mov [ssnac.wSid], 1Eh ; Subtype + mov [ssnac.dRi], 1Eh ; request-id + + mov [buff], 0 ; TLV type 06 + mov [buff+1], 6h ; + mov [buff+2], 0 ; TLV data length + mov [buff+3], 4 ; + ; + ; + mov ax, STATUS_DCDISABLED ; DC disabled + call htons + mov word [buff+4], ax + mov ax, STATUS_ONLINE + mov [status], ax + mov word [buff+6], ax + + mov eax, ssnac + mov ebx, buff + mov edx, 8 ; TLV head len+ data len + call sendsnac + + ; + ; Client READY command + ; + mov [ssnac.wFid], 1 ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 2 ; request-id + + mov eax, FAMILY_ARR + mov ebx, buff + push ecx + mov ecx, FA_LEN + call strcpy + pop ecx + + mov eax, ssnac + mov ebx, buff + mov edx, FA_LEN + call sendsnac + + + ; + ; Запрашиваем offline сообщения + ; + mov [ssnac.wFid], 15h ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 2 ; request-id + + mov word [buff], 0100h ; TLV type 01 + mov word [buff+2], 0A00h ; 00 0a Длина + mov word [buff+4], 0008h ; 08 00 + mov eax, UIN + call ascitoint + mov dword [buff+6], eax + + mov [buff+10], 003Ch ; 3C 00 - Запрос на оффлайновые сообщения + mov [buff+12], 0002 ; 02 00 - request sequence number + + mov edx, 14 ; Общий размер данных в буфере + + mov eax, ssnac + mov ebx, buff + call sendsnac + + + + jmp m_fin + + m_snac_13_other: + write_debug 'Unknown SNAC Family 13 Recived' + jmp m_fin + + + + + ; + ; Family 15 + ; + + m_snac_15: + + cmp dx, 3 + jz m_snac_15_3 + + jmp m_snac_15_other + + + ; + ; Server sends message #N + ; + m_snac_15_3: + ; + ; Определяем подтип принятого пакета + ; + + ;write_debug 'SNAC 15, 3' + + xor eax, eax + mov ax, word [mbuff+10] ; + SNAC.head size + cmp ax, 0100h ; 00 01 TLV type + jnz m_snac_tlv_err + + mov ax, word [mbuff+10+10] + cmp ax, 0041h ; Offline Message + jz m_snac_offline_mes + cmp ax, 0042h ; End messages + jz m_snac_offline_end + cmp ax, 07DAh + jz m_snac_meta_data + + + write_debug 'Unknown Subtype SNAC (15,3)' + jmp m_fin + + m_snac_offline_mes: + mov eax, MESS ; + call strlen ; Выводим строку с сообщением о отправителе и времени отправки + push ecx ; + mov ecx, eax ; + mov eax, MESS + mov ebx, buff + call strcpy + + mov eax, dword [mbuff+14+10] ; Sender UIN + lea ebx, [buff+ecx] ; После строчки о сообщении + call int2strd + + lea ebx, [ebx+eax] + mov [ebx], byte ' ' + inc ebx + + ; + Длина UIN + movzx eax, byte [mbuff+21+10] ; Day + call int2strd + + lea ebx, [ebx+eax] + mov [ebx], byte '.' + inc ebx + + + movzx eax, byte [mbuff+20+10] ;Mounth + call int2strd + + lea ebx, [ebx+eax] + mov [ebx], byte ' ' + inc ebx + + movzx eax, [mbuff+22+10] ; Hour + call int2strd + + lea ebx, [ebx+eax] + mov [ebx], byte ':' + inc ebx + + movzx eax, [mbuff+23+10] ; Minute + call int2strd + + lea ebx, [ebx+eax] + ;mov [ebx], byte ' ' + ;inc ebx + + mov [ebx], byte 0 ; Str end + mov eax, buff + xor ebx, ebx + + call writemsg + + movzx ecx, word [mbuff+26+10] ; Длина соообщения + lea eax, [mbuff+28+10] + mov ebx, buff + call strcpy + + mov [ebx+ecx], byte 0 + + mov eax, buff + call win2dos ;перекодируем + + mov ebx, 00FF0000h ;Цвет + + call writemsg + + + pop ecx + + jmp m_fin + + + m_snac_offline_end: + ; + ; Удаляем сообщения на сервере + ; + mov [ssnac.wFid], 15h ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 0602h ; request-id + + mov word [buff], 0100h ; 00 01 TLV.Type(1) - encapsulated META_DATA1 + mov word [buff+2], 0A00h ; 00 0A TLV.Length + mov word [buff+4], 0008h ; 08 00 data chunk size (TLV.Length-2) + mov eax, UIN + call ascitoint + mov dword [buff+6], eax ; xx xx xx xx (LE) client uin + mov word [buff+10], 003Eh ; 3E 00 (LE) data type: delete offline msgs request cmd + mov word [buff+12], 0007h ; xx xx (LE) request sequence number + + mov edx, 14 ; Размер данных + mov eax, ssnac + mov ebx, buff + call sendsnac + + + + jmp m_fin + + ; + ; Ответ на запрос о пользователях + ; + m_snac_meta_data: + ; + ; Определяем очередной подтип :-) + ; + mov ax, word [mbuff+10+14] + cmp ax, 0104h ;data subtype: META_SHORT_USERINFO + jz m_snac_short_userinfo + cmp ax, 00C8h + jz m_snac_basic_userinfo ;data subtype: META_BASIC_USERINFO + write_debug 'Unknown META DATA subtype' + jmp m_fin + + + + m_snac_short_userinfo: + ; + ; Из всей информации пока нужен только ник + ; + mov al, [mbuff+10+16] + cmp al, 0Ah ;success byte + jnz m_fin + + movzx eax, word [mbuff+10+12] ;request sequence number + ; + ; В запросе я использовал порядковый номер юзера в КЛ + lea ebx, [mbuff+10+19] ;nickname string + ; Длина строки не нужна, т.к. строка Null-Terminated + ;Определяем статус + mov ecx, 4 + imul ecx, eax + mov ecx, [stats+ecx] + + call loadbb + + + + jmp m_fin + + ; + ; тк SIQ на запрос короткой инфы отвечает + ; пакетом базовой информации, реализую пока только его + ; + m_snac_basic_userinfo: + mov al, [mbuff+10+16] + cmp al, 0Ah ;success byte + jnz m_fin + + movzx eax, word [mbuff+10+12] ;request sequence number + ; + ; В запросе я использовал порядковый номер юзера в КЛ + lea ebx, [mbuff+10+19] ;nickname string + ; Длина строки не нужна, т.к. строка Null-Terminated + ;Определяем статус + mov ecx, 4 + imul ecx, eax + mov ecx, [stats+ecx] + + call loadbb + + + + jmp m_fin + + m_snac_tlv_err: + write_debug 'TLV TYPE MISMATCH' + + jmp m_fin + + + m_snac_15_other: + + write_debug 'Unknown SNAC Family 15 Recived' + + jmp m_fin + + + m_other_snac: + write_debug 'Unknown SNAC recived' + jmp m_fin + + + + m_fin: + ;pop edx + ;pop ebx + ;pop eax + popad + popf + ret + +; Для перевода DWORD из Little Endian в Big Endian +; и наоборот :-) +; <--EAX DWORD +; -->EAX +; + ntohl: + htonl: + ;pushf + push ebx + ;push ecx + + xor ebx, ebx + + mov bl, ah + mov bh, al + shl ebx, 16 + + shr eax, 16 + mov bl, ah + mov bh, al + + mov eax, ebx + + ;pop ecx + pop ebx + ;popf + ret + + +; Для перевода WORD из Little Endian в Big Endian +; <--AX WORD +; -->AX WORD +; + + ntohs: + htons: + ;pushf + push ebx + + xor ebx, ebx + mov bl, ah + mov bh, al + mov eax, ebx + + pop ebx + ;popf + ret + +; +; парсит SNAC +; <--EAX указатель на SNAC_head +; <--EBX указатель на буффер +; -->EAX указатель начало данных = buffer+sizeof SNAC_head +; +; + snacpar: + pushf + push ecx + ;push edx + + mov cl, [ebx+1] ; Family (service) id number младший байт + mov ch, [ebx] ; старший + mov word [eax], cx + + mov cl, [ebx+3] ; Family subtype id number + mov ch, [ebx+2] ; + mov word [eax+2], cx + + mov cl, [ebx+5] ; SNAC flags + mov ch, [ebx+4] ; + mov word [eax+4], cx ; + + mov cl, [ebx+7] ; + mov ch, [ebx+6] ; + mov word [eax+8], cx ; SNAC request id + mov cl, [ebx+8] ; + mov ch, [ebx+7] ; + mov word [eax+6], cx ; + + add ebx, 10 ;Размер заголовка + mov eax, ebx + + + ;pop edx + pop ecx + popf + ret + +; +; парсит userinfo block +; FIXIT +; + +; userinfopar: +; pushf +; +; +; +; +; +; +; popf +; ret + +; +; посылка сообщения +; [eax] <-- текстовый буфер \ +; [ebx] <-- UIN / Null-terminated + + sendmsg: + pushf + pushad + push eax + push ebx + + mov [ssnac.wFid], 4h ; Family + mov [ssnac.wSid], 6 ; Subtype + mov [ssnac.dRi], 106h ; request-id + ; + ; Получаем время с запуска системы, для cookie + ; + mov eax, 26 + mov ebx, 9 + int 40h + + mov dword [buff], eax ; Cookie 1 + mov dword [buff+4], eax ; Cookie 2 + + mov word [buff+8], 0100h ; Message channel 00 01 + + + pop ebx + mov eax, ebx + call strlen + + mov [buff+10], al + mov ecx, eax + mov eax, ebx + lea ebx, [buff+11] + call strcpy + lea ecx, [ecx+11] + + mov word [buff+ecx], 0200h ; TLV.Type(0x02) - message data + + ;push ecx ; + ; TLV.Length + + mov word [buff+ecx+4], 0105h ; 05 01 01 - fragment version, 05 - fragment identifier + + mov word [buff+ecx+6], 0100h ; data length + + mov [buff+ecx+8], 01 ; byte array of required capabilities (1 - text) + + mov [buff+ecx+9], 01 ; fragment identifier (text message) + mov [buff+ecx+10], 01 ; fragment version + + pop ebx + mov eax, ebx + call strlen + mov edx, eax + lea eax, [eax+4] ; Длина сообщения + Message charset number+ Message language number + + call htons + mov word [buff+ecx+11], ax + + mov eax, edx + lea eax, [eax+13] ; + длина служебных данных + call htons + mov word [buff+ecx+2], ax + + + mov word [buff+ecx+13], 0700h ; Message charset number + mov word [buff+ecx+15], 0300h ; Message language number + + mov eax, ecx + mov ecx, edx ; Len + lea edx, [eax+17] + + mov eax, ebx ;Source + + lea ebx, [buff+edx] ;Dest + + call strcpy + lea ecx, [ecx+edx] ; +String length + + mov [buff+ecx], byte 0 + mov eax, ebx + call dos2win + + + mov word [buff+ecx], 0600h ; TLV.Type(0x06) - store message if recipient offline + mov word [buff+ecx+2], 0 ; TLV.Length + + lea edx, [ecx+4] ; +TLV_head length + mov eax, ssnac + mov ebx, buff + mov ecx, [socket] + call sendsnac + + + + popad + popf + ret + +; +; Запрос информации UINов +; + getinfo: + pushad + pushf + ; + ; SNAC (15,2) - Meta information request + ; + + mov [ssnac.wFid], 15h ; Family + mov [ssnac.wSid], 2 ; Subtype + mov [ssnac.dRi], 702h ; request-id + + mov word [buff], 0100h ;TLV.Type(1) - encapsulated META_DATA + mov word [buff+2], 1000h ; 00 10 TLV.Length + mov word [buff+4], 000Eh ; (LE) data chunk size (TLV.Length-2) + mov eax, UIN + call ascitoint + mov dword [buff+6], eax ;(LE) request owner uin + mov word [buff+10], 07D0h ;data type: META_DATA_REQ + ;mov word [buff+12], 0008h ; request sequence number <<<-- Может меняться FIXIT + mov word [buff+14], 04BAh ; data subtype: META_SHORTINFO_REQUEST + + mov ecx, [socket] + mov edx, 20 + + xor esi, esi ; Счетчик + xor eax, eax + + gi_loop: + mov ebx, esi + mov word [buff+12], bx ; request sequence number + mov ebx, UIN_LEN + imul ebx, esi + mov al, [uins+ebx] + cmp al, 0 + jz gi_end + + lea eax, [uins+ebx] + call ascitoint + mov dword [buff+16], eax + + mov eax, ssnac + mov ebx, buff + + call sendsnac + inc esi + cmp esi, UINS + jnc gi_end + jmp gi_loop + + + + + + + gi_end: + popf + popad + ret + +; +; Загружаем локальный КЛ на сервер для получения статуса юзеров +; + uploadkl: + pushf + pushad + ; + ; Add buddy(s) to contact list + ; + mov [ssnac.wFid], 3 ; Family + mov [ssnac.wSid], 4 ; Subtype + mov [ssnac.dRi], 4 ; request-id + + xor esi, esi ; Счетчик + xor edx, edx ; Заполнено байт + + ukk_loop: + mov ebx, UIN_LEN + imul ebx, esi + mov al, [uins+ebx] + cmp al, 0 + jz ukk_end + lea eax, [uins+ebx] + + call strlen + mov [buff+edx], al + inc edx + + mov ecx, eax + lea eax, [uins+ebx] ; Source + lea ebx, [buff+edx] + call strcpy + add edx, ecx + inc esi + cmp esi, UINS + jz ukk_end + jmp ukk_loop + + + + + + ukk_end: + mov eax, ssnac + mov ebx, buff + mov ecx, [socket] + call sendsnac + + popad + popf + ret + +; +; +; + sendkeep: + pushf + pushad + cmp [login], 2 + jnz @f + mov ax, [timer] + cmp ax, 300 ;60 c + jb @f + mov [timer], 0 + mov [flap.bId], FLAP_ID + mov [flap.bCh], 5 ;Keep alive + mov [flap.wDs], 0 + inc [seq] + mov ax, [seq] + mov [flap.wSn], ax + mov eax, flap + mov ebx, buff + mov ecx, [socket] + call sendflap + + + @@: + popad + popf + ret + + + + +; <--- initialised data ---> +DATA + lsz header,\ + ru, "KI",\ + en, "KI",\ + fr, "KI" + + +; +MESS db 'Message from ', 0 +CUSER db 'Current user: ', 0 + +; + +;ICQ_IP = 0x0A00A8C0 ; 192.168.0.10 + ICQ_IP = 0x99A10C40 +; +flap FLAP_head +rflap FLAP_head +; +ssnac SNAC_head ; для передачи SNAC +rsnac SNAC_head ; для принятого SNAC +; +ui UI_head ; User info +; +procinfo process_information +; +UIN db '123456789',0 +PASS db 'coolpass',0 +ID_STRING db 'ICQ Inc. - Product of ICQ (TM).2000b.4.65.1.3281.85',0 +;ID_STRING db 'ICQ Inc. - Product of ICQ (TM).2001b.5.17.1.3642.85',0 +CAPABILITIES db 053h, 054h, 0, 0, 097h, 0B1h, 027h, 051h, 024h, 03Ch, 043h, 034h, 0ADh, 022h, 0D6h, 0ABh,\ + 0F7h, 03Fh, 014h, 092h, 02Eh, 07Ah, 064h, 075h, 0FAh, 0DFh, 04Dh, 0C8h, 088h, 06Fh, 0EAh, 035h,\ + 095h, 0FDh, 0B6h, 0DFh, 09h, 046h, 013h, 044h, 04Ch, 07Fh, 011h, 0D1h, 082h, 022h, 044h, 045h,\ + 053h, 054h, 0, 0 +; +; From &RQ +; + +;CAPABILITIES db 0x09, 0x46, 0x13, 0x49, 0x4C, 0x7F, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45,\ ;...P.F.IL.TВ"DE +; 0x53, 0x54, 0x00, 0x00, 0x09, 0x46, 0x13, 0x44, 0x4C, 0x7F, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45,\ ;ST...F.DL.TВ"DE +; 0x53, 0x54, 0x00, 0x00, 0x09, 0x46, 0x13, 0x4E, 0x4C, 0x7F, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45,\ ;ST...F.NL.TВ"DE +; 0x53, 0x54, 0x00, 0x00, 0x09, 0x46, 0x00, 0x00, 0x4C, 0x7F, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45,\ ;ST...F..L.TВ"DE +; 0x53, 0x54, 0x00, 0x00, 0x26, 0x52, 0x51, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x02, 0x07, 0x09,\ ;ST..&RQinside... +; 0x00, 0x00, 0x00, 0x00 + + +C_LEN = 40h +;C_LEN = 80 +ICBM_PARAMS db 0, 0, 0, 0, 0, 0Bh, 01Fh, 040h, 3, 0E7h, 3, 0E7h, 0, 0, 0, 0 +ICBMP_LEN = 16 ; ^^^ from &RQ + + +; +; from &rq +; +FAMILY_ARR db 0x00, 0x01, 0x00, 0x03, 0x01, 0x10, 0x04, 0x7B, 0x00, 0x13, 0x00, 0x02, 0x01, 0x10, 0x04, 0x7B,\ + 0x00, 0x02, 0x00, 0x01, 0x01, 0x01, 0x04, 0x7B, 0x00, 0x03, 0x00, 0x01, 0x01, 0x10, 0x04, 0x7B,\ + 0x00, 0x15, 0x00, 0x01, 0x01, 0x10, 0x04, 0x7B, 0x00, 0x04, 0x00, 0x01, 0x01, 0x10, 0x04, 0x7B,\ + 0x00, 0x06, 0x00, 0x01, 0x01, 0x10, 0x04, 0x7B, 0x00, 0x09, 0x00, 0x01, 0x01, 0x10, 0x04, 0x7B,\ + 0x00, 0x0A, 0x00, 0x01, 0x01, 0x10, 0x04, 0x7B, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x06, 0x6A + + + + + +FA_LEN = 50h + +; +ID_NUM = 010Ah +MAJOR = 05h +;MAJOR = 04h +;MINOR = 041h +MINOR = 011h +LESSER = 01h +;BUILD = 0CD1h +BUILD = 0E3Ah +DISTR = 055h +TCB_ESTABLISHED = 4 +TCB_CLOSED = 11 +; +CL_LANG db 'en',0 +CL_COUNTRY db 'us',0 + + +sbuff db 1024 dup 0 ; Буфер для передачи используется внутри sendflap + +rbuff db 1024 dup 0 ; Приемный буфер +tbuff db 512 dup 0 ; Для TLV +srv_cookie db 512 dup 0 ; Куки для авторизации +bos_address db 128 dup 0 ; Адрес BOS сервера +cookie_len dw 0 ; Длина куки +seq dw 0 ; Sequence number +bos_ip dd 0 +bos_port dd 0 +status dw 0 ; status + +mbuff db 2048 dup 0 ; Для приема +MBUFF_SIZE = 2048 + +hrf db 0 ; Флаг приема заголовка + +mouse_flag dd 0 +socket dd 0 +login db 0 + +msg_cookie1 dd 0 ; Используются для потверждения приема сообщений +msg_cookie2 dd 0 ; + +curruser db 0 ; текущий пользователь, которому будут отправляться сообщения + ; - Номер в КЛ по порядку + + +timer dw 0 + +;ltest db "ADMIN",0 + + + +; +; EDITBOXES +; +inputbuff: + rb 512 + +inputbox edit_box 490,10,460,0xffffff,0x6a9480,0,0xAABBCC,0,511,inputbuff,ed_focus,0,0 + + +; <--- uninitialised data ---> +UDATA + + +MEOS_APP_END +; <--- end of MenuetOS application ---> \ No newline at end of file diff --git a/programs/network/icq/trunk/lang.inc b/programs/network/icq/trunk/lang.inc new file mode 100644 index 0000000000..30c0149bd9 --- /dev/null +++ b/programs/network/icq/trunk/lang.inc @@ -0,0 +1 @@ +lang fix ru \ No newline at end of file diff --git a/programs/network/icq/trunk/macros.inc b/programs/network/icq/trunk/macros.inc new file mode 100644 index 0000000000..bcf2e9fda5 --- /dev/null +++ b/programs/network/icq/trunk/macros.inc @@ -0,0 +1,502 @@ +@^ fix macro comment { +^@ fix } + + +macro m2m dest,src { + push src + pop dest +} + + +macro iglobal { + IGlobals equ IGlobals, + macro __IGlobalBlock { } + +macro uglobal { + UGlobals equ UGlobals, + macro __UGlobalBlock { } + +endg fix } ; Use endg for ending iglobal and uglobal blocks. + + +macro IncludeIGlobals{ + macro IGlobals dummy,[n] \{ __IGlobalBlock + purge __IGlobalBlock \} + match I, IGlobals \{ I \} } + +macro IncludeUGlobals{ + macro UGlobals dummy,[n] \{ + \common + \local begin, size + begin = $ + virtual at $ + \forward + __UGlobalBlock + purge __UGlobalBlock + \common + size = $ - begin + end virtual + rb size + \} + match U, UGlobals \{ U \} } + +uglobal +endg + +iglobal +endg + + +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + IncludeIGlobals + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + IncludeUGlobals + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + +; macro for defining multiline text data +struc mls [sstring] + { + forward + local ssize + virtual at 0 + db sstring ; mod + ssize = $ + end virtual + db ssize + db sstring + common + db -1 ; mod + } + + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + name db data + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + forward + if lang eq lng + db data + end if + common + .size = $-name + end if +} + +macro szc name,elsz,[data] { ; from MFAR [mike.dld] + common + local s,m + m = 0 + if used name + label name + forward + virtual at 0 + db data + s = $ + end virtual + d#elsz s + if m < s + m = s + end if + db data + common + .size = $-name + .maxl = m + end if +} + +macro lszc name,elsz,[lng,data] { ; from MFAR [mike.dld] + common + local s,m,c + m = 0 + c = 0 + if used name + label name + forward + if lang eq lng + virtual at 0 + db data + s = $ + end virtual + d#elsz s + if m < s + m = s + end if + db data + c = c+1 + end if + common + .size = $-name + .maxl = m + .count = c + end if +} + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + + +include 'config.inc' +;__CPU_type equ p5 +SYSENTER_VAR equ 0 + +macro mcall a,b,c,d,e,f { ; mike.dld, updated by Ghost for Fast System Calls + local ..ret_point + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + + if __CPU_type eq p5 + int 0x40 + else + if __CPU_type eq p6 + push ebp + mov ebp, esp + push ..ret_point ; it may be 2 or 5 byte + sysenter + ..ret_point: + pop edx + pop ecx + + else + if __CPU_type eq k6 + push ecx + syscall + pop ecx + else + display 'ERROR : unknown CPU type (set to p5)', 10, 13 + __CPU_type equ p5 + int 0x40 + end if + end if + end if +} + + +; ------------------------- +macro header a,[b] { + common + use32 + org 0 + db 'MENUET',a + forward + if b eq + dd 0 + else + dd b + end if } +macro section name { align 16 + label name } +macro func name { + if ~used name + display 'FUNC NOT USED: ',`name,13,10 + else + align 4 + name: + ;diff16 `name,0,name +;pushad +;pushfd +;dps `name +;newline +;mcall 5,1 +;popfd +;popad +} +macro endf { end if } + +macro diff16 title,l1,l2 + { + local s,d + s = l2-l1 + display title,': 0x' + repeat 8 + d = '0' + s shr ((8-%) shl 2) and $0F + if d > '9' + d = d + 'A'-'9'-1 + end if + display d + end repeat + display 13,10 + } + +macro diff10 title,l1,l2 + { + local s,d,z,m + s = l2-l1 + z = 0 + m = 1000000000 + display title,': ' + repeat 10 + d = '0' + s / m + s = s - (s/m)*m + m = m / 10 + if d <> '0' + z = 1 + end if + if z <> 0 + display d + end if + end repeat + display 13,10 + } + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro RGB [a] { + common + match (r=,g=,b),a \{ + \dd ((r) shl 16) or ((g) shl 8) or (b) + \} +} + + +struc POINT _t,_dx,_dy { + .x _t _dx + .y _t _dy +} + +; structure definition helper +include 'struct.inc' + +struct RECT + left dd ? + top dd ? + right dd ? + bottom dd ? +ends + +struct BOX + left dd ? + top dd ? + width dd ? + height dd ? +ends + +; structures used in MeOS +struct process_information + cpu_usage dd ? ; +0 + window_stack_position dw ? ; +4 + window_stack_value dw ? ; +6 + dw ? ; +8 + process_name rb 12 ; +10 + memory_start dd ? ; +22 + used_memory dd ? ; +26 + PID dd ? ; +30 + box BOX ; +34 + slot_state dw ? ; +50 + dw ? ; +52 + client_box BOX ; +54 + wnd_state db ? ; +70 + rb (1024-71) +ends + +struct system_colors + frame dd ? + grab dd ? + grab_button dd ? + grab_button_text dd ? + grab_text dd ? + work dd ? + work_button dd ? + work_button_text dd ? + work_text dd ? + work_graph dd ? +ends + +struct FILEDATE + Second db ? + Minute db ? + Hour db ? + db ? + Day db ? + Month db ? + Year dw ? +ends + +struct FILEINFO + Attributes dd ? + IsUnicode db ? + db 3 dup(?) + DateCreate FILEDATE + DateAccess FILEDATE + DateModify FILEDATE + Size dq ? +ends + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/programs/network/icq/trunk/struct.inc b/programs/network/icq/trunk/struct.inc new file mode 100644 index 0000000000..947a84e89a --- /dev/null +++ b/programs/network/icq/trunk/struct.inc @@ -0,0 +1,180 @@ + +; Macroinstructions for defining data structures + +macro struct name + { fields@struct equ name + match child parent, name \{ fields@struct equ child,fields@\#parent \} + sub@struct equ + struc db [val] \{ \common fields@struct equ fields@struct,.,db, \} + struc dw [val] \{ \common fields@struct equ fields@struct,.,dw, \} + struc du [val] \{ \common fields@struct equ fields@struct,.,du, \} + struc dd [val] \{ \common fields@struct equ fields@struct,.,dd, \} + struc dp [val] \{ \common fields@struct equ fields@struct,.,dp, \} + struc dq [val] \{ \common fields@struct equ fields@struct,.,dq, \} + struc dt [val] \{ \common fields@struct equ fields@struct,.,dt, \} + struc rb count \{ fields@struct equ fields@struct,.,db,count dup (?) \} + struc rw count \{ fields@struct equ fields@struct,.,dw,count dup (?) \} + struc rd count \{ fields@struct equ fields@struct,.,dd,count dup (?) \} + struc rp count \{ fields@struct equ fields@struct,.,dp,count dup (?) \} + struc rq count \{ fields@struct equ fields@struct,.,dq,count dup (?) \} + struc rt count \{ fields@struct equ fields@struct,.,dt,count dup (?) \} + macro db [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,db, \} + macro dw [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dw, \} + macro du [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,du, \} + macro dd [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dd, \} + macro dp [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dp, \} + macro dq [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dq, \} + macro dt [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dt, \} + macro rb count \{ \local anonymous + fields@struct equ fields@struct,anonymous,db,count dup (?) \} + macro rw count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dw,count dup (?) \} + macro rd count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dd,count dup (?) \} + macro rp count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dp,count dup (?) \} + macro rq count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dq,count dup (?) \} + macro rt count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dt,count dup (?) \} + macro union \{ fields@struct equ fields@struct,,union,< + sub@struct equ union \} + macro struct \{ fields@struct equ fields@struct,,substruct,< + sub@struct equ substruct \} + virtual at 0 } + +macro ends + { match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt + restruc rb,rw,rd,rp,rq,rt + purge db,dw,du,dd,dp,dq,dt + purge rb,rw,rd,rp,rq,rt + purge union,struct + match name=,fields,fields@struct \\{ fields@struct equ + make@struct name,fields + fields@\\#name equ fields \\} + end virtual \} + match any, sub@struct \{ fields@struct equ fields@struct> \} + restore sub@struct } + +macro make@struct name,[field,type,def] + { common + if $ + display 'Error: definition of ',`name,' contains illegal instructions.',0Dh,0Ah + err + end if + local define + define equ name + forward + local sub + match , field \{ make@substruct type,name,sub def + define equ define,.,sub, \} + match any, field \{ define equ define,.#field,type, \} + common + match fields, define \{ define@struct fields \} } + +macro define@struct name,[field,type,def] + { common + local list + list equ + forward + if ~ field eq . + name#field type def + sizeof.#name#field = $ - name#field + else + rb sizeof.#type + end if + local value + match any, list \{ list equ list, \} + list equ list + common + sizeof.#name = $ + restruc name + match values, list \{ + struc name value \\{ + match any, fields@struct \\\{ fields@struct equ fields@struct,.,name, \\\} + match , fields@struct \\\{ label . + forward + match , value \\\\{ field type def \\\\} + match any, value \\\\{ field type value + if ~ field eq . + rb sizeof.#name#field - ($-field) + end if \\\\} + common \\\} \\} \} } + +macro enable@substruct + { macro make@substruct substruct,parent,name,[field,type,def] + \{ \common + \local define + define equ parent,name + \forward + \local sub + match , field \\{ match any, type \\\{ enable@substruct + make@substruct type,name,sub def + purge make@substruct + define equ define,.,sub, \\\} \\} + match any, field \\{ define equ define,.\#field,type, \\} + \common + match fields, define \\{ define@\#substruct fields \\} \} } + +enable@substruct + +macro define@union parent,name,[field,type,def] + { common + virtual at 0 + forward + if ~ field eq . + virtual at 0 + parent#field type def + sizeof.#parent#field = $ - parent#field + end virtual + if sizeof.#parent#field > $ + rb sizeof.#parent#field - $ + end if + else if sizeof.#type > $ + rb sizeof.#type - $ + end if + common + sizeof.#name = $ + end virtual + struc name [value] \{ \common + label .\#name + last@union equ + forward + match any, last@union \\{ virtual at .\#name + field type def + end virtual \\} + match , last@union \\{ match , value \\\{ field type def \\\} + match any, value \\\{ field type value \\\} \\} + last@union equ field + common rb sizeof.#name - ($ - .\#name) \} } + +macro define@substruct parent,name,[field,type,def] + { common + virtual at 0 + forward + if ~ field eq . + parent#field type def + sizeof.#parent#field = $ - parent#field + else + rb sizeof.#type + end if + local value + common + sizeof.#name = $ + end virtual + struc name value \{ + label .\#name + forward + match , value \\{ field type def \\} + match any, value \\{ field type value + if ~ field eq . + rb sizeof.#parent#field - ($-field) + end if \\} + common \} }