Rev 5708 | Rev 5720 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5708 | Rev 5715 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; VNC client for KolibriOS ;; |
6 | ;; VNC client for KolibriOS ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
11 | ;; Version 2, June 1991 ;; |
11 | ;; Version 2, June 1991 ;; |
12 | ;; ;; |
12 | ;; ;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
14 | 14 | ||
15 | thread_start: |
15 | thread_start: |
16 | 16 | ||
17 | mcall 40, 0 ; disable all events for this thread |
17 | mcall 40, 0 ; disable all events for this thread |
- | 18 | ||
- | 19 | ; Extract port number from server address |
|
- | 20 | mov esi, serveraddr |
|
- | 21 | @@: |
|
- | 22 | lodsb |
|
- | 23 | test al, al |
|
- | 24 | jz .port_done |
|
- | 25 | cmp al, ':' |
|
- | 26 | jne @r |
|
- | 27 | mov byte[esi-1], 0 ; replace colon with 0 byte, we dont want to upset getaddrinfo |
|
- | 28 | xor eax, eax |
|
- | 29 | xor ebx, ebx ; port number |
|
- | 30 | @@: |
|
- | 31 | lodsb |
|
- | 32 | test al, al |
|
- | 33 | jz @f |
|
- | 34 | sub al, '0' |
|
- | 35 | jb err_dns |
|
- | 36 | cmp al, 9 |
|
- | 37 | ja err_dns |
|
- | 38 | lea ebx, [ebx*4+ebx] |
|
- | 39 | lea ebx, [ebx*2+eax] |
|
- | 40 | jmp @b |
|
- | 41 | @@: |
|
- | 42 | xchg bl, bh |
|
- | 43 | mov [sockaddr1.port], bx |
|
- | 44 | .port_done: |
|
18 | 45 | ||
19 | ; resolve name |
46 | ; Resolve hostname |
20 | push esp ; reserve stack place |
47 | push esp ; reserve stack place |
21 | invoke getaddrinfo, serveraddr, 0, 0, esp |
48 | invoke getaddrinfo, serveraddr, 0, 0, esp |
22 | pop esi |
49 | pop esi |
23 | ; test for error |
- | |
24 | test eax, eax |
50 | test eax, eax |
25 | jnz err_dns |
51 | jnz err_dns |
26 | 52 | ||
27 | mov eax, [esi+addrinfo.ai_addr] |
53 | mov eax, [esi+addrinfo.ai_addr] |
28 | mov eax, [eax+sockaddr_in.sin_addr] |
54 | mov eax, [eax+sockaddr_in.sin_addr] |
29 | mov [sockaddr1.ip], eax |
55 | mov [sockaddr1.ip], eax |
- | 56 | invoke freeaddrinfo, esi |
|
30 | 57 | ||
31 | DEBUGF 1, "Connecting to %u.%u.%u.%u:%u\n", \ |
58 | DEBUGF 1, "Connecting to %u.%u.%u.%u:%u\n", \ |
32 | [sockaddr1.ip]:1, [sockaddr1.ip+1]:1, [sockaddr1.ip+2]:1, [sockaddr1.ip+3]:1, \ |
59 | [sockaddr1.ip]:1, [sockaddr1.ip+1]:1, [sockaddr1.ip+2]:1, [sockaddr1.ip+3]:1, \ |
33 | [sockaddr1.port]:2 |
60 | [sockaddr1.port]:2 |
34 | 61 | ||
35 | invoke freeaddrinfo, esi |
- | |
36 | 62 | ; Open socket |
|
37 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
63 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
38 | cmp eax, -1 |
64 | cmp eax, -1 |
39 | je err_sock |
65 | je err_sock |
40 | - | ||
41 | mov [socketnum], eax |
66 | mov [socketnum], eax |
- | 67 | ||
- | 68 | ; Connect to the server |
|
42 | mcall connect, [socketnum], sockaddr1, 18 |
69 | mcall connect, [socketnum], sockaddr1, 18 |
43 | cmp eax, -1 |
70 | cmp eax, -1 |
44 | je err_connect |
71 | je err_connect |
- | 72 | ||
45 | 73 | ; Wait for handshake from server |
|
46 | ; TODO: implement timeout |
74 | ; TODO: implement timeout |
47 | call wait_for_data |
- | |
48 | 75 | call wait_for_data |
|
49 | cmp dword[receive_buffer], "RFB " |
76 | cmp dword[receive_buffer], "RFB " |
- | 77 | jne err_proto |
|
- | 78 | ||
50 | jne err_proto |
79 | ; Reply to handshake |
51 | DEBUGF 1, "Sending handshake\n" |
80 | DEBUGF 1, "Sending handshake\n" |
52 | mcall send, [socketnum], HandShake, 12, 0 |
81 | mcall send, [socketnum], HandShake, 12, 0 |
53 | call wait_for_data |
82 | call wait_for_data |
54 | 83 | ||
55 | cmp dword[receive_buffer], 0x01000000 ; no security |
84 | cmp dword[receive_buffer], 0x01000000 ; no security |
56 | je initialize |
85 | je initialize |
57 | cmp dword[receive_buffer], 0x02000000 ; VNC security |
86 | cmp dword[receive_buffer], 0x02000000 ; VNC security |
58 | je vnc_security |
87 | je vnc_security |
59 | 88 | ||
60 | jmp err_security |
89 | jmp err_security |
61 | 90 | ||
62 | vnc_security: |
91 | vnc_security: |
63 | 92 | ||
64 | mov dword[password], 0 |
93 | mov dword[password], 0 |
65 | mov dword[password+4], 0 |
94 | mov dword[password+4], 0 |
66 | 95 | ||
67 | and [USERbox.flags], not ed_focus |
96 | and [USERbox.flags], not ed_focus |
68 | or [USERbox.flags], ed_disabled |
97 | or [USERbox.flags], ed_disabled |
69 | or [PASSbox.flags], ed_focus |
98 | or [PASSbox.flags], ed_focus |
70 | 99 | ||
71 | mov [status], STATUS_REQ_LOGIN |
100 | mov [status], STATUS_REQ_LOGIN |
72 | inc [update_gui] |
101 | inc [update_gui] |
73 | @@: |
102 | @@: |
74 | mcall 5, 10 |
103 | mcall 5, 10 |
75 | cmp [status], STATUS_LOGIN |
104 | cmp [status], STATUS_LOGIN |
76 | je @f |
105 | je @f |
77 | cmp [status], STATUS_REQ_LOGIN |
106 | cmp [status], STATUS_REQ_LOGIN |
78 | je @r |
107 | je @r |
79 | mcall -1 |
108 | mcall -1 |
80 | @@: |
109 | @@: |
81 | DEBUGF 1, "VNC authentication\n" |
110 | DEBUGF 1, "VNC authentication\n" |
82 | 111 | ||
83 | ; Bit reverse the password and create DES keys |
112 | ; Bit reverse the password and create DES keys |
84 | 113 | ||
85 | mov ebx, dword[password] |
114 | mov ebx, dword[password] |
86 | mov edx, ebx |
115 | mov edx, ebx |
87 | and ebx, 0xf0f0f0f0 |
116 | and ebx, 0xf0f0f0f0 |
88 | shr ebx, 4 |
117 | shr ebx, 4 |
89 | and edx, 0x0f0f0f0f |
118 | and edx, 0x0f0f0f0f |
90 | shl edx, 4 |
119 | shl edx, 4 |
91 | or ebx, edx |
120 | or ebx, edx |
92 | mov edx, ebx |
121 | mov edx, ebx |
93 | and ebx, 0xCCCCCCCC |
122 | and ebx, 0xCCCCCCCC |
94 | shr ebx, 2 |
123 | shr ebx, 2 |
95 | and edx, 0x33333333 |
124 | and edx, 0x33333333 |
96 | shl edx, 2 |
125 | shl edx, 2 |
97 | or ebx, edx |
126 | or ebx, edx |
98 | mov edx, ebx |
127 | mov edx, ebx |
99 | and ebx, 0xAAAAAAAA |
128 | and ebx, 0xAAAAAAAA |
100 | shr ebx, 1 |
129 | shr ebx, 1 |
101 | and edx, 0x55555555 |
130 | and edx, 0x55555555 |
102 | shl edx, 1 |
131 | shl edx, 1 |
103 | or ebx, edx |
132 | or ebx, edx |
104 | bswap ebx |
133 | bswap ebx |
105 | 134 | ||
106 | mov eax, dword[password+4] |
135 | mov eax, dword[password+4] |
107 | mov edx, eax |
136 | mov edx, eax |
108 | and eax, 0xf0f0f0f0 |
137 | and eax, 0xf0f0f0f0 |
109 | shr eax, 4 |
138 | shr eax, 4 |
110 | and edx, 0x0f0f0f0f |
139 | and edx, 0x0f0f0f0f |
111 | shl edx, 4 |
140 | shl edx, 4 |
112 | or eax, edx |
141 | or eax, edx |
113 | mov edx, eax |
142 | mov edx, eax |
114 | and eax, 0xCCCCCCCC |
143 | and eax, 0xCCCCCCCC |
115 | shr eax, 2 |
144 | shr eax, 2 |
116 | and edx, 0x33333333 |
145 | and edx, 0x33333333 |
117 | shl edx, 2 |
146 | shl edx, 2 |
118 | or eax, edx |
147 | or eax, edx |
119 | mov edx, eax |
148 | mov edx, eax |
120 | and eax, 0xAAAAAAAA |
149 | and eax, 0xAAAAAAAA |
121 | shr eax, 1 |
150 | shr eax, 1 |
122 | and edx, 0x55555555 |
151 | and edx, 0x55555555 |
123 | shl edx, 1 |
152 | shl edx, 1 |
124 | or edx, eax |
153 | or edx, eax |
125 | bswap edx |
154 | bswap edx |
126 | 155 | ||
127 | mov edi, keys |
156 | mov edi, keys |
128 | call DES_create_keys |
157 | call DES_create_keys |
129 | 158 | ||
130 | ; Encrypt message with DES |
159 | ; Encrypt message with DES |
131 | 160 | ||
132 | mov ebx, dword[receive_buffer+4] |
161 | mov ebx, dword[receive_buffer+4] |
133 | mov edx, dword[receive_buffer+8] |
162 | mov edx, dword[receive_buffer+8] |
134 | call encrypt_DES |
163 | call encrypt_DES |
135 | mov dword[receive_buffer+4], ebx |
164 | mov dword[receive_buffer+4], ebx |
136 | mov dword[receive_buffer+8], edx |
165 | mov dword[receive_buffer+8], edx |
137 | 166 | ||
138 | mov ebx, dword[receive_buffer+12] |
167 | mov ebx, dword[receive_buffer+12] |
139 | mov edx, dword[receive_buffer+16] |
168 | mov edx, dword[receive_buffer+16] |
140 | call encrypt_DES |
169 | call encrypt_DES |
141 | mov dword[receive_buffer+12], ebx |
170 | mov dword[receive_buffer+12], ebx |
142 | mov dword[receive_buffer+16], edx |
171 | mov dword[receive_buffer+16], edx |
143 | 172 | ||
144 | ; Blank out the password and key fields in RAM |
173 | ; Blank out the password and key fields in RAM |
145 | 174 | ||
146 | mov edi, password |
175 | mov edi, password |
147 | mov ecx, 384/4 |
176 | mov ecx, 384/4 |
148 | xor eax, eax |
177 | xor eax, eax |
149 | rep stosd |
178 | rep stosd |
150 | 179 | ||
151 | ; Send the authentication response to server |
180 | ; Send the authentication response to server |
152 | 181 | ||
153 | mcall send, [socketnum], receive_buffer+4, 16, 0 |
182 | mcall send, [socketnum], receive_buffer+4, 16, 0 |
154 | 183 | ||
155 | call wait_for_data |
184 | call wait_for_data |
156 | cmp dword[receive_buffer], 0 |
185 | cmp dword[receive_buffer], 0 |
157 | jne err_login |
186 | jne err_login |
158 | ; jmp initialize |
187 | ; jmp initialize |
159 | 188 | ||
160 | initialize: |
189 | initialize: |
161 | DEBUGF 1, "Sending ClientInit\n" |
190 | DEBUGF 1, "Sending ClientInit\n" |
162 | mcall send, [socketnum], ClientInit, 1, 0 |
191 | mcall send, [socketnum], ClientInit, 1, 0 |
163 | 192 | ||
164 | call wait_for_data ; now the server should send init message |
193 | call wait_for_data ; now the server should send init message |
165 | 194 | ||
166 | DEBUGF 1, "Serverinit: bpp: %u depth: %u bigendian: %u truecolor: %u\n", \ |
195 | DEBUGF 1, "Serverinit: bpp: %u depth: %u bigendian: %u truecolor: %u\n", \ |
167 | [receive_buffer+framebuffer.pixelformat.bpp]:1, \ |
196 | [receive_buffer+framebuffer.pixelformat.bpp]:1, \ |
168 | [receive_buffer+framebuffer.pixelformat.depth]:1, \ |
197 | [receive_buffer+framebuffer.pixelformat.depth]:1, \ |
169 | [receive_buffer+framebuffer.pixelformat.big_endian]:1, \ |
198 | [receive_buffer+framebuffer.pixelformat.big_endian]:1, \ |
170 | [receive_buffer+framebuffer.pixelformat.true_color]:1 |
199 | [receive_buffer+framebuffer.pixelformat.true_color]:1 |
171 | 200 | ||
172 | mov eax, dword[receive_buffer+framebuffer.width] |
201 | mov eax, dword[receive_buffer+framebuffer.width] |
173 | mov dword[FramebufferUpdateRequest.width], eax |
202 | mov dword[FramebufferUpdateRequest.width], eax |
174 | bswap eax |
203 | bswap eax |
175 | mov dword[screen], eax |
204 | mov dword[screen], eax |
176 | DEBUGF 1, "Screen width=%u, height=%u\n", [screen.width]:2, [screen.height]:2 |
205 | DEBUGF 1, "Screen width=%u, height=%u\n", [screen.width]:2, [screen.height]:2 |
177 | 206 | ||
178 | DEBUGF 1, "Sending pixel format\n" |
207 | DEBUGF 1, "Sending pixel format\n" |
179 | if BITS_PER_PIXEL = 8 |
208 | if BITS_PER_PIXEL = 8 |
180 | mcall send, [socketnum], SetPixelFormat8, 20, 0 |
209 | mcall send, [socketnum], SetPixelFormat8, 20, 0 |
181 | else if BITS_PER_PIXEL = 16 |
210 | else if BITS_PER_PIXEL = 16 |
182 | mcall send, [socketnum], SetPixelFormat16, 20, 0 |
211 | mcall send, [socketnum], SetPixelFormat16, 20, 0 |
183 | else |
212 | else |
184 | mcall send, [socketnum], SetPixelFormat24, 20, 0 |
213 | mcall send, [socketnum], SetPixelFormat24, 20, 0 |
185 | end if |
214 | end if |
186 | 215 | ||
187 | DEBUGF 1, "Sending encoding info\n" |
216 | DEBUGF 1, "Sending encoding info\n" |
188 | mcall send, [socketnum], SetEncodings, SetEncodings.length, 0 |
217 | mcall send, [socketnum], SetEncodings, SetEncodings.length, 0 |
189 | 218 | ||
190 | ; Set main window caption to servername |
219 | ; Set main window caption to servername |
191 | mov ecx, dword[receive_buffer+framebuffer.name_length] |
220 | mov ecx, dword[receive_buffer+framebuffer.name_length] |
192 | bswap ecx |
221 | bswap ecx |
193 | cmp ecx, 64 |
222 | cmp ecx, 64 |
194 | jbe @f |
223 | jbe @f |
195 | mov ecx, 64 |
224 | mov ecx, 64 |
196 | @@: |
225 | @@: |
197 | lea esi, [receive_buffer+framebuffer.name] |
226 | lea esi, [receive_buffer+framebuffer.name] |
198 | mov edi, servername |
227 | mov edi, servername |
199 | rep movsb |
228 | rep movsb |
200 | mov byte[edi], 0 |
229 | mov byte[edi], 0 |
201 | mov [name.dash], "-" |
230 | mov [name.dash], "-" |
202 | 231 | ||
203 | ; Tell the main thread we are ready for business! |
232 | ; Tell the main thread we are ready for business! |
204 | mov [status], STATUS_CONNECTED |
233 | mov [status], STATUS_CONNECTED |
205 | 234 | ||
206 | ; Request initial update |
235 | ; Request initial framebuffer update from server |
207 | mov [FramebufferUpdateRequest.inc], 0 |
236 | mov [FramebufferUpdateRequest.inc], 0 |
208 | 237 | ||
209 | request_fbu: |
238 | request_fbu: |
210 | DEBUGF 1, "Requesting framebuffer update\n" |
239 | DEBUGF 1, "Requesting framebuffer update\n" |
211 | mcall send, [socketnum], FramebufferUpdateRequest, 10, 0 |
240 | mcall send, [socketnum], FramebufferUpdateRequest, 10, 0 |
212 | mov [FramebufferUpdateRequest.inc], 1 |
241 | mov [FramebufferUpdateRequest.inc], 1 |
213 | 242 | ||
214 | thread_loop: |
243 | thread_loop: |
215 | call read_data ; Read the data into the buffer |
244 | call read_data ; Read the data into the buffer |
216 | 245 | ||
217 | lodsb |
246 | lodsb |
218 | cmp al, 0 |
247 | cmp al, 0 |
219 | je framebufferupdate |
248 | je framebufferupdate |
220 | cmp al, 1 |
249 | cmp al, 1 |
221 | je setcolourmapentries |
250 | je setcolourmapentries |
222 | cmp al, 2 |
251 | cmp al, 2 |
223 | je bell |
252 | je bell |
224 | cmp al, 3 |
253 | cmp al, 3 |
225 | je servercuttext |
254 | je servercuttext |
226 | 255 | ||
227 | DEBUGF 2, "Unknown server command: %u\n", al |
256 | DEBUGF 2, "Unknown server command: %u\n", al |
228 | jmp thread_loop |
257 | jmp thread_loop |
229 | 258 | ||
230 | framebufferupdate: |
259 | framebufferupdate: |
231 | 260 | ||
232 | @@: |
261 | @@: |
233 | lea eax, [esi+6] |
262 | lea eax, [esi+6] |
234 | cmp [datapointer], eax |
263 | cmp [datapointer], eax |
235 | jae @f |
264 | jae @f |
236 | call read_data.more |
265 | call read_data.more |
237 | jmp @b |
266 | jmp @b |
238 | @@: |
267 | @@: |
239 | 268 | ||
240 | inc esi ; padding |
269 | inc esi ; padding |
241 | lodsw |
270 | lodsw |
242 | xchg al, ah |
271 | xchg al, ah |
243 | mov [rectangles], ax |
272 | mov [rectangles], ax |
244 | DEBUGF 1, "Framebufferupdate: %u rectangles\n", ax |
273 | DEBUGF 1, "Framebufferupdate: %u rectangles\n", ax |
245 | 274 | ||
246 | rectangle_loop: |
275 | rectangle_loop: |
247 | 276 | ||
248 | @@: |
277 | @@: |
249 | lea eax, [esi+12] |
278 | lea eax, [esi+12] |
250 | cmp [datapointer], eax |
279 | cmp [datapointer], eax |
251 | jae @f |
280 | jae @f |
252 | call read_data.more |
281 | call read_data.more |
253 | jmp @b |
282 | jmp @b |
254 | @@: |
283 | @@: |
255 | 284 | ||
256 | xor eax, eax |
285 | xor eax, eax |
257 | lodsw |
286 | lodsw |
258 | xchg al, ah |
287 | xchg al, ah |
259 | mov [rectangle.x], eax |
288 | mov [rectangle.x], eax |
260 | lodsw |
289 | lodsw |
261 | xchg al, ah |
290 | xchg al, ah |
262 | mov [rectangle.y], eax |
291 | mov [rectangle.y], eax |
263 | lodsw |
292 | lodsw |
264 | xchg al, ah |
293 | xchg al, ah |
265 | mov [rectangle.width], eax |
294 | mov [rectangle.width], eax |
266 | lodsw |
295 | lodsw |
267 | xchg al, ah |
296 | xchg al, ah |
268 | mov [rectangle.height], eax |
297 | mov [rectangle.height], eax |
269 | 298 | ||
270 | lodsd ; encoding |
299 | lodsd ; encoding |
271 | bswap eax |
300 | bswap eax |
272 | DEBUGF 1, "rectangle: width=%u height=%u x=%u y=%u encoding: ",\ |
301 | DEBUGF 1, "Rectangle: x=%u y=%u width=%u height=%u encoding: ",\ |
273 | [rectangle.width]:2, [rectangle.height]:2, [rectangle.x]:2, [rectangle.y]:2 |
302 | [rectangle.x]:2, [rectangle.y]:2, [rectangle.width]:2, [rectangle.height]:2 |
274 | 303 | ||
275 | cmp eax, 0 |
304 | cmp eax, 0 |
276 | je encoding_raw |
305 | je encoding_raw |
277 | cmp eax, 1 |
306 | cmp eax, 1 |
278 | je encoding_CopyRect |
307 | je encoding_CopyRect |
279 | cmp eax, 2 |
308 | cmp eax, 2 |
280 | je encoding_RRE |
309 | je encoding_RRE |
281 | ; cmp eax, 5 |
310 | ; cmp eax, 5 |
282 | ; je encoding_hextile |
311 | ; je encoding_hextile |
283 | ; cmp eax, 15 |
312 | ; cmp eax, 15 |
284 | ; je encoding_TRLE |
313 | ; je encoding_TRLE |
285 | ; cmp eax, 16 |
314 | ; cmp eax, 16 |
286 | ; je encoding_ZRLE |
315 | ; je encoding_ZRLE |
287 | 316 | ||
288 | DEBUGF 2, "unknown encoding: %u\n", eax |
317 | DEBUGF 2, "unknown encoding: %u\n", eax |
289 | jmp thread_loop |
318 | jmp thread_loop |
290 | 319 | ||
291 | next_rectangle: |
320 | next_rectangle: |
292 | inc [update_framebuffer] |
321 | inc [update_framebuffer] |
293 | dec [rectangles] |
322 | dec [rectangles] |
294 | jnz rectangle_loop |
323 | jnz rectangle_loop |
295 | jmp request_fbu |
324 | jmp request_fbu |
296 | 325 | ||
297 | 326 | ||
298 | setcolourmapentries: |
327 | setcolourmapentries: |
299 | 328 | ||
300 | DEBUGF 1, "Server sent SetColourMapEntries message\n" |
329 | DEBUGF 1, "Server sent SetColourMapEntries message\n" |
301 | 330 | ||
302 | @@: |
331 | @@: |
303 | lea eax, [esi+5] |
332 | lea eax, [esi+5] |
304 | cmp [datapointer], eax |
333 | cmp [datapointer], eax |
305 | jae @f |
334 | jae @f |
306 | call read_data.more |
335 | call read_data.more |
307 | jmp @b |
336 | jmp @b |
308 | @@: |
337 | @@: |
309 | 338 | ||
310 | inc esi ; padding |
339 | inc esi ; padding |
311 | 340 | ||
312 | xor eax, eax |
341 | xor eax, eax |
313 | lodsw ; first color (just ignore for now) |
342 | lodsw ; first color (just ignore for now) |
314 | 343 | ||
315 | lodsw ; number of colors (use to find end of message) |
344 | lodsw ; number of colors (use to find end of message) |
316 | xchg al, ah |
345 | xchg al, ah |
317 | lea eax, [eax*2+eax] |
346 | lea eax, [eax*2+eax] |
318 | shl eax, 1 |
347 | shl eax, 1 |
319 | @@: |
348 | @@: |
320 | push eax |
349 | push eax |
321 | add eax, esi |
350 | add eax, esi |
322 | cmp [datapointer], eax |
351 | cmp [datapointer], eax |
323 | jae @f |
352 | jae @f |
324 | call read_data.more |
353 | call read_data.more |
325 | pop eax |
354 | pop eax |
326 | jmp @b |
355 | jmp @b |
327 | @@: |
356 | @@: |
328 | pop eax |
357 | pop eax |
329 | 358 | ||
330 | add esi, eax ; Just skip it for now. |
359 | add esi, eax ; Just skip it for now. |
331 | jmp thread_loop |
360 | jmp thread_loop |
332 | 361 | ||
333 | 362 | ||
334 | bell: |
363 | bell: |
335 | mcall 55, 55, , , beep |
364 | mcall 55, 55, , , beep |
336 | jmp thread_loop |
365 | jmp thread_loop |
337 | 366 | ||
338 | 367 | ||
339 | servercuttext: |
368 | servercuttext: |
340 | 369 | ||
341 | DEBUGF 1, "Server cut text\n" |
370 | DEBUGF 1, "Server cut text\n" |
342 | 371 | ||
343 | @@: |
372 | @@: |
344 | lea eax, [esi+7] |
373 | lea eax, [esi+7] |
345 | cmp [datapointer], eax |
374 | cmp [datapointer], eax |
346 | jae @f |
375 | jae @f |
347 | call read_data.more |
376 | call read_data.more |
348 | jmp @b |
377 | jmp @b |
349 | @@: |
378 | @@: |
350 | 379 | ||
351 | add esi, 3 |
380 | add esi, 3 |
352 | lodsd |
381 | lodsd |
353 | bswap eax |
382 | bswap eax |
354 | mov ecx, eax |
383 | mov ecx, eax |
355 | 384 | ||
356 | @@: |
385 | @@: |
357 | lea eax, [esi+ecx] |
386 | lea eax, [esi+ecx] |
358 | cmp [datapointer], eax |
387 | cmp [datapointer], eax |
359 | jae @f |
388 | jae @f |
360 | call read_data.more |
389 | call read_data.more |
361 | jmp @b |
390 | jmp @b |
362 | @@: |
391 | @@: |
363 | 392 | ||
364 | ; TODO: paste text to clipboard |
393 | ; TODO: paste text to clipboard |
365 | 394 | ||
366 | DEBUGF 1, "%u bytes of text\n", ecx |
395 | DEBUGF 1, "%u bytes of text\n", ecx |
367 | add esi, ecx |
396 | add esi, ecx |
368 | jmp thread_loop |
397 | jmp thread_loop |
369 | 398 | ||
370 | 399 | ||
371 | read_data: |
400 | read_data: |
372 | mov [datapointer], receive_buffer |
401 | mov [datapointer], receive_buffer |
373 | mov esi, receive_buffer |
402 | mov esi, receive_buffer |
374 | .more: |
403 | .more: |
375 | push ebx ecx edx esi edi |
404 | push ebx ecx edx esi edi |
376 | neg esi |
405 | neg esi |
377 | add esi, receive_buffer + RECEIVE_BUFFER_SIZE |
406 | add esi, receive_buffer + RECEIVE_BUFFER_SIZE |
378 | jz .buffer_end_reached |
407 | jz .buffer_end_reached |
379 | xor edi, edi |
408 | xor edi, edi |
380 | mcall recv, [socketnum], [datapointer] |
409 | mcall recv, [socketnum], [datapointer] |
381 | pop edi esi edx ecx ebx |
410 | pop edi esi edx ecx ebx |
382 | cmp eax, -1 |
411 | cmp eax, -1 |
383 | je err_sock |
412 | je err_sock |
384 | test eax, eax |
413 | test eax, eax |
385 | jz err_disconnected |
414 | jz err_disconnected |
386 | add [datapointer], eax |
415 | add [datapointer], eax |
387 | ret |
416 | ret |
388 | 417 | ||
389 | .buffer_end_reached: |
418 | .buffer_end_reached: |
390 | ; Buffer is full, first needed data by program is pointed to by esi. |
419 | ; Buffer is full, first needed data by program is pointed to by esi. |
391 | ; Move all usefull data to begin of buffer |
420 | ; Move all usefull data to begin of buffer |
392 | cmp esi, receive_buffer |
421 | cmp esi, receive_buffer |
393 | je err_proto |
422 | je err_proto |
394 | mov ecx, [datapointer] |
423 | mov ecx, [datapointer] |
395 | sub ecx, esi |
424 | sub ecx, esi |
396 | mov edi, receive_buffer |
425 | mov edi, receive_buffer |
397 | rep movsb |
426 | rep movsb |
398 | mov [datapointer], edi ; new end of data |
427 | mov [datapointer], edi ; new end of data |
399 | mov esi, receive_buffer ; new start of data |
428 | mov esi, receive_buffer ; new start of data |
400 | jmp .more |
429 | jmp .more |
401 | 430 | ||
402 | 431 | ||
403 | 432 | ||
404 | wait_for_data: ; FIXME: add timeout |
433 | wait_for_data: ; FIXME: add timeout |
405 | mcall recv, [socketnum], receive_buffer, 4096, 0 ; MSG_DONTWAIT |
434 | mcall recv, [socketnum], receive_buffer, 4096, 0 ; MSG_DONTWAIT |
406 | cmp eax, -1 |
435 | cmp eax, -1 |
407 | je err_sock |
436 | je err_sock |
408 | test eax, eax |
437 | test eax, eax |
409 | jz err_disconnected |
438 | jz err_disconnected |
410 | ret |
439 | ret |
411 | 440 | ||
412 | 441 | ||
413 | err_disconnected: |
442 | err_disconnected: |
414 | mov [status], STATUS_DISCONNECTED |
443 | mov [status], STATUS_DISCONNECTED |
415 | inc [update_gui] |
444 | inc [update_gui] |
416 | mcall -1 |
445 | mcall -1 |
417 | 446 | ||
418 | err_dns: |
447 | err_dns: |
419 | mov [status], STATUS_DNS_ERR |
448 | mov [status], STATUS_DNS_ERR |
420 | inc [update_gui] |
449 | inc [update_gui] |
421 | mcall -1 |
450 | mcall -1 |
422 | 451 | ||
423 | err_sock: |
452 | err_sock: |
424 | mov [status], STATUS_SOCK_ERR |
453 | mov [status], STATUS_SOCK_ERR |
425 | inc [update_gui] |
454 | inc [update_gui] |
426 | mcall -1 |
455 | mcall -1 |
427 | 456 | ||
428 | err_connect: |
457 | err_connect: |
429 | mov [status], STATUS_CONNECT_ERR |
458 | mov [status], STATUS_CONNECT_ERR |
430 | inc [update_gui] |
459 | inc [update_gui] |
431 | mcall -1 |
460 | mcall -1 |
432 | ret |
461 | ret |
433 | 462 | ||
434 | err_proto: |
463 | err_proto: |
435 | mov [status], STATUS_PROTO_ERR |
464 | mov [status], STATUS_PROTO_ERR |
436 | inc [update_gui] |
465 | inc [update_gui] |
437 | mcall -1 |
466 | mcall -1 |
438 | ret |
467 | ret |
439 | 468 | ||
440 | err_security: |
469 | err_security: |
441 | mov [status], STATUS_SECURITY_ERR |
470 | mov [status], STATUS_SECURITY_ERR |
442 | inc [update_gui] |
471 | inc [update_gui] |
443 | mcall -1 |
472 | mcall -1 |
444 | ret |
473 | ret |
445 | 474 | ||
446 | err_login: |
475 | err_login: |
447 | mov [status], STATUS_LOGIN_FAILED |
476 | mov [status], STATUS_LOGIN_FAILED |
448 | inc [update_gui] |
477 | inc [update_gui] |
449 | mcall -1 |
478 | mcall -1 |
450 | ret |
479 | ret |