source: trunk/src/kernel32/conin.cpp@ 22018

Last change on this file since 22018 was 10471, checked in by sandervl, 22 years ago

DBCS fixes for console & resource functions

File size: 36.6 KB
Line 
1/* $Id: conin.cpp,v 1.18 2004-02-19 13:03:05 sandervl Exp $ */
2
3/*
4 * Win32 Console API Translation for OS/2
5 * 1998/02/10 Patrick Haller (haller@zebra.fh-weingarten.de)
6 * Project Odin Software License can be found in LICENSE.TXT
7 */
8
9
10#ifdef DEBUG
11#define DEBUG_LOCAL
12#define DEBUG_LOCAL2
13#endif
14
15
16/*****************************************************************************
17 * Remark *
18 *****************************************************************************
19*/
20
21
22/*****************************************************************************
23 * Includes *
24 *****************************************************************************/
25
26#define INCL_WIN
27#define INCL_DOSMEMMGR
28#define INCL_DOSSEMAPHORES
29#define INCL_DOSERRORS
30#define INCL_DOSPROCESS
31#define INCL_DOSMODULEMGR
32#define INCL_VIO
33#define INCL_AVIO
34#include <os2wrap.h> //Odin32 OS/2 api wrappers
35
36#include <win32api.h>
37#include <misc.h>
38#include <string.h>
39#include <stdlib.h>
40
41#include "conwin.h" // Windows Header for console only
42#include "HandleManager.h"
43#include "HMDevice.h"
44#include "Conin.H"
45#include "Console2.h"
46#include <heapstring.h>
47
48#define DBG_LOCALLOG DBG_conin
49#include "dbglocal.h"
50
51
52/*****************************************************************************
53 * Name : DWORD HMDeviceConsoleInClass::CreateFile
54 * Purpose : this is called from the handle manager if a CreateFile() is
55 * performed on a handle
56 * Parameters: LPCSTR lpFileName name of the file / device
57 * PHMHANDLEDATA pHMHandleData data of the NEW handle
58 * PVOID lpSecurityAttributes ignored
59 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
60 * Variables :
61 * Result :
62 * Remark : @@@PH CONIN$ handles should be exclusive
63 * reject other requests to this device
64 * Status : NO_ERROR - API succeeded
65 * other - what is to be set in SetLastError
66 *
67 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
68 *****************************************************************************/
69
70DWORD HMDeviceConsoleInClass::CreateFile (LPCSTR lpFileName,
71 PHMHANDLEDATA pHMHandleData,
72 PVOID lpSecurityAttributes,
73 PHMHANDLEDATA pHMHandleDataTemplate)
74{
75#ifdef DEBUG_LOCAL
76 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
77 lpHMDeviceName,
78 lpFileName,
79 pHMHandleData->hHMHandle,
80 lpSecurityAttributes,
81 pHMHandleDataTemplate);
82#endif
83
84 return(NO_ERROR);
85}
86
87/*****************************************************************************
88 * Name : DWORD HMDeviceConsoleInClass::GetFileType
89 * Purpose : determine the handle type
90 * Parameters: PHMHANDLEDATA pHMHandleData
91 * Variables :
92 * Result : API returncode
93 * Remark :
94 * Status :
95 *
96 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
97 *****************************************************************************/
98
99DWORD HMDeviceConsoleInClass::GetFileType(PHMHANDLEDATA pHMHandleData)
100{
101 dprintf(("KERNEL32: HMDeviceConsoleInClass::GetFileType %s(%08x)\n",
102 lpHMDeviceName,
103 pHMHandleData));
104
105 return FILE_TYPE_CHAR;
106}
107
108/*****************************************************************************
109 * Name :
110 * Purpose :
111 * Parameters:
112 * Variables :
113 * Result :
114 * Remark :
115 * Status :
116 *
117 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
118 *****************************************************************************/
119
120BOOL HMDeviceConsoleInClass::ReadFile(PHMHANDLEDATA pHMHandleData,
121 LPCVOID lpBuffer,
122 DWORD nNumberOfBytesToRead,
123 LPDWORD lpNumberOfBytesRead,
124 LPOVERLAPPED lpOverlapped,
125 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
126{
127 ULONG ulCounter; /* character counter for the queue loop */
128 PSZ pszTarget; /* pointer to target buffer */
129 APIRET rc; /* API returncode */
130 INPUT_RECORD InputRecord; /* buffer for the event to be read */
131 ULONG ulPostCounter; /* semaphore post counter */
132 BOOL fLoop = TRUE; /* set to false if function may return to caller */
133
134#ifdef DEBUG_LOCAL
135 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)\n",
136 lpHMDeviceName,
137 pHMHandleData->hHMHandle,
138 lpBuffer,
139 nNumberOfBytesToRead,
140 lpNumberOfBytesRead,
141 lpOverlapped);
142#endif
143
144 if(lpCompletionRoutine) {
145 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
146 }
147
148 ulCounter = 0; /* read ascii chars from queue */
149 pszTarget = (PSZ)lpBuffer;
150
151 /* block if no key events are in the queue */
152 for (;fLoop;) /* until we got some characters */
153 {
154 iConsoleInputQueryEvents(pConsoleInput, QUERY_EVENT_WAIT); /* if queue is currently empty */
155
156 do
157 {
158 rc = iConsoleInputEventPop(&InputRecord); /* get event from queue */
159 if (rc == NO_ERROR) /* if we've got a valid event in the queue */
160 {
161 //@@@PH other events are discarded!
162 if ( (InputRecord.EventType == KEY_EVENT) && /* check event type */
163 (InputRecord.Event.KeyEvent.bKeyDown == TRUE) )
164 {
165 // console in line input mode ?
166 if (pConsoleInput->dwConsoleMode & ENABLE_LINE_INPUT)
167 {
168 // continue until buffer full or CR entered
169 // Note: CRLF is actually returned at the end of the buffer!
170 if (InputRecord.Event.KeyEvent.uChar.AsciiChar == 0x0d)
171 fLoop = FALSE;
172 }
173 else
174 // return on any single key in buffer :)
175 // fLoop = FALSE;
176 // @@@PH 2000/08/10 changed behaviour to return ALL input events
177 // recorded in the console.
178 fLoop = (iConsoleInputQueryEvents(pConsoleInput, QUERY_EVENT_PEEK) != 0);
179
180 // record key stroke
181 if (pConsoleInput->dwConsoleMode & ENABLE_PROCESSED_INPUT)
182 {
183 // filter special characters first
184 switch (InputRecord.Event.KeyEvent.uChar.AsciiChar)
185 {
186 case 0x00:
187 // Ascii values of 0x00 are sent e.g. for SHIFT-DOWN
188 // key events, etc.
189 break;
190
191 case 0x03: // ctrl-c is filtered!
192 // @@@PH we're supposed to call a ctrl-c break handler here!
193 break;
194
195 case 0x0d: // CR
196 // CR is automatically expanded to CRLF if in line input mode!
197 if (pConsoleInput->dwConsoleMode & ENABLE_LINE_INPUT)
198 {
199 *pszTarget = 0x0d; // CR
200 pszTarget++;
201 ulCounter++;
202 if (ulCounter < nNumberOfBytesToRead) // check for room
203 {
204 *pszTarget = 0x0a; // LF
205 pszTarget++;
206 ulCounter++;
207 }
208
209 if (pConsoleInput->dwConsoleMode & ENABLE_ECHO_INPUT)
210 HMWriteFile(pConsoleGlobals->hConsoleBuffer,
211 pszTarget-2,
212 2,
213 &ulPostCounter, /* dummy result */
214 NULL, NULL);
215
216 }
217
218 break;
219
220 case 0x08: // backspace
221 if (ulCounter > 0)
222 {
223 //@@@PH erase character on screen!
224 ulCounter--;
225 pszTarget--;
226 /* local echo enabled ? */
227 if (pConsoleInput->dwConsoleMode & ENABLE_ECHO_INPUT)
228 HMWriteFile(pConsoleGlobals->hConsoleBuffer,
229 &InputRecord.Event.KeyEvent.uChar.AsciiChar,
230 1,
231 &ulPostCounter, /* dummy result */
232 NULL, NULL);
233 }
234 break;
235
236 default:
237 // OK, for the rest ...
238 *pszTarget = InputRecord.Event.KeyEvent.uChar.AsciiChar;
239 dprintf(("KERNEL32:CONIN$: Debug: recorded key (%c - %02xh)\n",
240 *pszTarget,
241 *pszTarget));
242
243 pszTarget++;
244 ulCounter++;
245 /* local echo enabled ? */
246 if (pConsoleInput->dwConsoleMode & ENABLE_ECHO_INPUT)
247 HMWriteFile(pConsoleGlobals->hConsoleBuffer,
248 &InputRecord.Event.KeyEvent.uChar.AsciiChar,
249 1,
250 &ulPostCounter, /* dummy result */
251 NULL, NULL);
252 }
253 }
254 else
255 {
256 *pszTarget = InputRecord.Event.KeyEvent.uChar.AsciiChar;
257 dprintf(("KERNEL32:CONIN$: Debug: recorded key (%c - %02xh)\n",
258 *pszTarget,
259 *pszTarget));
260
261 pszTarget++;
262 ulCounter++;
263
264 /* local echo enabled ? */
265 if (pConsoleInput->dwConsoleMode & ENABLE_ECHO_INPUT)
266 HMWriteFile(pConsoleGlobals->hConsoleBuffer,
267 &InputRecord.Event.KeyEvent.uChar.AsciiChar,
268 1,
269 &ulPostCounter, /* dummy result */
270 NULL, NULL);
271 }
272
273 // buffer filled?
274 if (ulCounter >= nNumberOfBytesToRead) /* at buffer's end ? */
275 fLoop = FALSE;
276 }
277 /* Note: other events are discarded */
278 }
279 }
280 while (rc == NO_ERROR);
281 }
282
283 *lpNumberOfBytesRead = ulCounter; /* write result */
284
285 return(TRUE); /* OK */
286}
287
288
289/*****************************************************************************
290 * Name :
291 * Purpose :
292 * Parameters:
293 * Variables :
294 * Result :
295 * Remark :
296 * Status :
297 *
298 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
299 *****************************************************************************/
300
301BOOL HMDeviceConsoleInClass::WriteFile(PHMHANDLEDATA pHMHandleData,
302 LPCVOID lpBuffer,
303 DWORD nNumberOfBytesToWrite,
304 LPDWORD lpNumberOfBytesWritten,
305 LPOVERLAPPED lpOverlapped,
306 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
307{
308
309#ifdef DEBUG_LOCAL
310 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass:WriteFile %s(%08x,%08x,%08x,%08x,%08x)\n",
311 lpHMDeviceName,
312 pHMHandleData->hHMHandle,
313 lpBuffer,
314 nNumberOfBytesToWrite,
315 lpNumberOfBytesWritten,
316 lpOverlapped);
317#endif
318
319 SetLastError(ERROR_ACCESS_DENIED_W);
320 return FALSE;
321}
322
323
324/*****************************************************************************
325 * Name :
326 * Purpose :
327 * Parameters:
328 * Variables :
329 * Result :
330 * Remark :
331 * Status :
332 *
333 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
334 *****************************************************************************/
335
336DWORD HMDeviceConsoleInClass::_DeviceRequest (PHMHANDLEDATA pHMHandleData,
337 ULONG ulRequestCode,
338 ULONG arg1,
339 ULONG arg2,
340 ULONG arg3,
341 ULONG arg4)
342{
343 switch (ulRequestCode)
344 {
345 case DRQ_FLUSHCONSOLEINPUTBUFFER:
346 return (HMDeviceConsoleInClass::
347 FlushConsoleInputBuffer(pHMHandleData));
348
349 case DRQ_GETCONSOLEMODE:
350 return (HMDeviceConsoleInClass
351 ::GetConsoleMode(pHMHandleData,
352 (LPDWORD)arg1));
353
354 case DRQ_GETNUMBEROFCONSOLEINPUTEVENTS:
355 return (HMDeviceConsoleInClass::
356 GetNumberOfConsoleInputEvents(pHMHandleData,
357 (LPDWORD)arg1));
358
359 case DRQ_PEEKCONSOLEINPUTA:
360 return (HMDeviceConsoleInClass::
361 PeekConsoleInputA(pHMHandleData,
362 (PINPUT_RECORD)arg1,
363 (DWORD) arg2,
364 (LPDWORD) arg3));
365
366 case DRQ_PEEKCONSOLEINPUTW:
367 return (HMDeviceConsoleInClass::
368 PeekConsoleInputW(pHMHandleData,
369 (PINPUT_RECORD)arg1,
370 (DWORD) arg2,
371 (LPDWORD) arg3));
372
373
374 case DRQ_READCONSOLEA:
375 return (HMDeviceConsoleInClass::
376 ReadConsoleA(pHMHandleData,
377 (CONST VOID*) arg1,
378 (DWORD) arg2,
379 (LPDWORD) arg3,
380 (LPVOID) arg4));
381
382 case DRQ_READCONSOLEW:
383 return (HMDeviceConsoleInClass::
384 ReadConsoleW(pHMHandleData,
385 (CONST VOID*) arg1,
386 (DWORD) arg2,
387 (LPDWORD) arg3,
388 (LPVOID) arg4));
389
390 case DRQ_READCONSOLEINPUTA:
391 return (HMDeviceConsoleInClass::
392 ReadConsoleInputA(pHMHandleData,
393 (PINPUT_RECORD)arg1,
394 (DWORD)arg2,
395 (LPDWORD)arg3));
396
397 case DRQ_READCONSOLEINPUTW:
398 return (HMDeviceConsoleInClass::
399 ReadConsoleInputW(pHMHandleData,
400 (PINPUT_RECORD)arg1,
401 (DWORD)arg2,
402 (LPDWORD)arg3));
403
404 case DRQ_SETCONSOLEMODE:
405 return (HMDeviceConsoleInClass
406 ::SetConsoleMode(pHMHandleData,
407 (DWORD)arg1));
408
409 case DRQ_WRITECONSOLEINPUTA:
410 return (HMDeviceConsoleInClass::
411 WriteConsoleInputA(pHMHandleData,
412 (PINPUT_RECORD)arg1,
413 (DWORD)arg2,
414 (LPDWORD)arg3));
415
416 case DRQ_WRITECONSOLEINPUTW:
417 return (HMDeviceConsoleInClass::
418 WriteConsoleInputW(pHMHandleData,
419 (PINPUT_RECORD)arg1,
420 (DWORD)arg2,
421 (LPDWORD)arg3));
422
423 }
424
425#ifdef DEBUG_LOCAL
426 WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass:_DeviceRequest %s(%08x,%08x,%08x,%08x,%08x,%08x) unknown request\n",
427 lpHMDeviceName,
428 pHMHandleData->hHMHandle,
429 ulRequestCode,
430 arg1,
431 arg2,
432 arg3,
433 arg4);
434#endif
435
436 SetLastError(ERROR_INVALID_FUNCTION_W); /* request not implemented */
437 return(FALSE); /* we assume this indicates API call failed */
438}
439
440
441/*****************************************************************************
442 * Name : BOOL HMDeviceConsoleInClass::FlushConsoleInputBuffer
443 * Purpose : flushes all events from the input queue
444 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
445 * Variables :
446 * Result :
447 * Remark :
448 * Status : UNTESTED
449 *
450 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
451 *****************************************************************************/
452
453BOOL HMDeviceConsoleInClass::FlushConsoleInputBuffer(PHMHANDLEDATA pHMHandleData)
454{
455 ULONG ulCounter; /* loop counter */
456
457#ifdef DEBUG_LOCAL2
458 WriteLog("KERNEL32/CONSOLE: CONIN$::FlushConsoleInputBuffer(%08x).\n",
459 pHMHandleData);
460#endif
461
462 //get all pending events
463 iConsoleInputQueryEvents(pConsoleInput, QUERY_EVENT_PEEK);
464
465 pConsoleInput->ulIndexFree = 0;
466 pConsoleInput->ulIndexEvent = 0;
467 pConsoleInput->ulEvents = 0;
468
469 for (ulCounter = 0;
470 ulCounter < CONSOLE_INPUTQUEUESIZE;
471 ulCounter++)
472 pConsoleInput->arrInputRecord[ulCounter].EventType = 0x0000; /* free event */
473
474 return (TRUE);
475}
476
477
478/*****************************************************************************
479 * Name : DWORD HMDeviceConsoleInClass::GetConsoleMode
480 * Purpose : queries the current console mode
481 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
482 * LPDWORD lpMode
483 * Variables :
484 * Result :
485
486 * Remark :
487 * Status : UNTESTED
488 *
489 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
490 *****************************************************************************/
491
492DWORD HMDeviceConsoleInClass::GetConsoleMode(PHMHANDLEDATA pHMHandleData,
493 LPDWORD lpMode)
494{
495#ifdef DEBUG_LOCAL2
496 WriteLog("KERNEL32/CONSOLE: CONIN$::GetConsoleMode(%08x,%08x).\n",
497 pHMHandleData,
498 lpMode);
499#endif
500
501 *lpMode = pConsoleInput->dwConsoleMode; /* return current console mode */
502
503 return (TRUE);
504}
505
506
507/*****************************************************************************
508 * Name : DWORD HMDeviceConsoleInClass::GetNumberOfConsoleInputEvents
509 * Purpose : queries the current number of events in the input queue
510 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
511 * LPDWORD lpNumberOfEvents - return number of events
512 * Variables :
513 * Result :
514 * Remark :
515 * Status : UNTESTED
516 *
517 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
518 *****************************************************************************/
519
520BOOL HMDeviceConsoleInClass::GetNumberOfConsoleInputEvents(PHMHANDLEDATA pHMHandleData,
521 LPDWORD lpNumberOfEvents)
522{
523#ifdef DEBUG_LOCAL2
524 WriteLog("KERNEL32/CONSOLE: CONIN$::GetNumberOfConsoleInputEvents(%08x,%08x).\n",
525 pHMHandleData,
526 lpNumberOfEvents);
527#endif
528
529 //get all pending events and return number of events
530 *lpNumberOfEvents = iConsoleInputQueryEvents(pConsoleInput, QUERY_EVENT_PEEK);
531
532 return (TRUE);
533}
534
535
536/*****************************************************************************
537 * Name : DWORD HMDeviceConsoleInClass::PeekConsoleInputA
538 * Purpose : peeks events placed in the console input queue
539 * Parameters: PHMHANDLEDATA pHMHandleData - current handle data
540 * PINPUT_RECORD pirBuffer - target buffer for events
541 * DWORD cInRecords - number of input records
542 * LPDWORD lpcRead - returns number of events stored
543 * Variables :
544 * Result : TRUE if successful, FALSE otherwise
545 * Remark : if queue is completely filled and no event is free,
546 * loop will scan over queue multiple times, until target
547 * buffer is filled. It does not check ulCounter to stop
548 * when one scan of the queue is complete.
549 * Status : UNTESTED
550 *
551 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
552 *****************************************************************************/
553
554DWORD HMDeviceConsoleInClass::PeekConsoleInputA(PHMHANDLEDATA pHMHandleData,
555 PINPUT_RECORD pirBuffer,
556 DWORD cInRecords,
557 LPDWORD lpcRead)
558{
559 ULONG ulCounter; /* loop counter */
560 ULONG ulCurrentEvent; /* index of current event in the queue */
561 PINPUT_RECORD pirEvent; /* pointer to current queue element */
562
563#ifdef DEBUG_LOCAL2
564 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::PeekConsoleInputA(%08x,%08x,%08x,%08x).\n",
565 pHMHandleData,
566 pirBuffer,
567 cInRecords,
568 lpcRead);
569#endif
570
571 if (iConsoleInputQueryEvents(pConsoleInput, QUERY_EVENT_PEEK) == 0) /* if queue is currently empty */
572 {
573 *lpcRead = 0; /* no events read from queue */
574 return (TRUE); /* OK, we're done */
575 }
576
577
578 for (ulCounter = 0,
579 ulCurrentEvent = pConsoleInput->ulIndexEvent,
580 pirEvent = &pConsoleInput->arrInputRecord[pConsoleInput->ulIndexEvent];
581
582 ulCounter < cInRecords;
583
584 ulCounter++,
585 ulCurrentEvent++,
586 pirEvent++,
587 pirBuffer++)
588 {
589 if (ulCurrentEvent > CONSOLE_INPUTQUEUESIZE) /* reaching after end of que*/
590 {
591 ulCurrentEvent = 0; /* then start over from beginning of queue */
592 pirEvent = pConsoleInput->arrInputRecord;
593 }
594
595 if (pirEvent->EventType == 0x0000) /* no more events ? */
596 break; /* leave loop then */
597
598 memcpy(pirEvent, /* copy event data */
599 pirBuffer,
600 sizeof(INPUT_RECORD));
601 }
602
603 *lpcRead = ulCounter; /* return number of events read */
604 return (TRUE); /* OK, we're done */
605}
606
607
608/*****************************************************************************
609 * Name : DWORD HMDeviceConsoleInClass::PeekConsoleInputW
610 * Purpose : peeks events placed in the console input queue
611 * Parameters: PHMHANDLEDATA pHMHandleData - current handle data
612 * PINPUT_RECORD pirBuffer - target buffer for events
613 * DWORD cInRecords - number of input records
614 * LPDWORD lpcRead - returns number of events stored
615 * Variables :
616 * Result : TRUE if successful, FALSE otherwise
617 * Remark : if queue is completely filled and no event is free,
618 * loop will scan over queue multiple times, until target
619 * buffer is filled. It does not check ulCounter to stop
620 * when one scan of the queue is complete.
621 * Status : UNTESTED
622 *
623 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
624 *****************************************************************************/
625
626DWORD HMDeviceConsoleInClass::PeekConsoleInputW(PHMHANDLEDATA pHMHandleData,
627 PINPUT_RECORD pirBuffer,
628 DWORD cInRecords,
629 LPDWORD lpcRead)
630{
631 ULONG ulCounter; /* loop counter */
632 ULONG ulCurrentEvent; /* index of current event in the queue */
633 PINPUT_RECORD pirEvent; /* pointer to current queue element */
634
635#ifdef DEBUG_LOCAL2
636 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::PeekConsoleInputW(%08x,%08x,%08x,%08x).\n",
637 pHMHandleData,
638 pirBuffer,
639 cInRecords,
640 lpcRead);
641#endif
642
643 if (iConsoleInputQueryEvents(pConsoleInput, QUERY_EVENT_PEEK) == 0) /* if queue is currently empty */
644 {
645 *lpcRead = 0; /* no events read from queue */
646 return (TRUE); /* OK, we're done */
647 }
648
649
650 for (ulCounter = 0,
651 ulCurrentEvent = pConsoleInput->ulIndexEvent,
652 pirEvent = &pConsoleInput->arrInputRecord[pConsoleInput->ulIndexEvent];
653
654 ulCounter < cInRecords;
655
656 ulCounter++,
657 ulCurrentEvent++,
658 pirEvent++,
659 pirBuffer++)
660 {
661 if (ulCurrentEvent > CONSOLE_INPUTQUEUESIZE) /* reaching after end of que*/
662 {
663 ulCurrentEvent = 0; /* then start over from beginning of queue */
664 pirEvent = pConsoleInput->arrInputRecord;
665 }
666
667 if (pirEvent->EventType == 0x0000) /* no more events ? */
668 break; /* leave loop then */
669
670 memcpy(pirEvent, /* copy event data */
671 pirBuffer,
672 sizeof(INPUT_RECORD));
673 }
674
675 *lpcRead = ulCounter; /* return number of events read */
676 return (TRUE); /* OK, we're done */
677}
678
679
680/*****************************************************************************
681 * Name : DWORD HMDeviceConsoleInClass::ReadConsoleA
682 * Purpose : read a string from the console
683 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
684 * LPWORD lpwAttribute
685 * DWORD cWriteCells
686 * COORD dwWriteCoord
687 * LPDWORD lpcWritten
688 * Variables :
689 * Result :
690 * Remark :
691 * Status : UNTESTED
692 *
693 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
694 *****************************************************************************/
695
696DWORD HMDeviceConsoleInClass::ReadConsoleA(PHMHANDLEDATA pHMHandleData,
697 CONST VOID* lpvBuffer,
698 DWORD cchToRead,
699 LPDWORD lpcchRead,
700 LPVOID lpvReserved)
701{
702 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
703
704#ifdef DEBUG_LOCAL2
705 WriteLog("KERNEL32/CONSOLE: CONIN$::ReadConsoleA(%08x,%08x,%u,%08x,%08x).\n",
706 pHMHandleData,
707 lpvBuffer,
708 cchToRead,
709 lpcchRead,
710 lpvReserved);
711#endif
712
713 /* simply forward the request to that routine */
714 return (HMDeviceConsoleInClass::ReadFile(pHMHandleData,
715 lpvBuffer,
716 cchToRead,
717 lpcchRead,
718 NULL, NULL));
719}
720
721/*****************************************************************************
722 * Name : DWORD HMDeviceConsoleInClass::ReadConsoleW
723 * Purpose : write a string to the console
724 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
725 * LPWORD lpwAttribute
726 * DWORD cWriteCells
727 * COORD dwWriteCoord
728 * LPDWORD lpcWritten
729 * Variables :
730 * Result :
731 * Remark :
732 * Status : UNTESTED
733 *
734 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
735 *****************************************************************************/
736
737DWORD HMDeviceConsoleInClass::ReadConsoleW(PHMHANDLEDATA pHMHandleData,
738 CONST VOID* lpvBuffer,
739 DWORD cchToRead,
740 LPDWORD lpcchRead,
741 LPVOID lpvReserved)
742{
743 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
744 DWORD dwResult;
745 LPSTR lpstrAscii;
746
747#ifdef DEBUG_LOCAL2
748 WriteLog("KERNEL32/CONSOLE: CONIN$::ReadConsoleW(%08x,%08x,%u,%08x,%08x).\n",
749 pHMHandleData,
750 lpvBuffer,
751 cchToRead,
752 lpcchRead,
753 lpvReserved);
754#endif
755
756 // create ascii buffer
757 lpstrAscii = (LPSTR)HEAP_malloc(cchToRead * sizeof( WCHAR ));
758 if (lpstrAscii == NULL)
759 return ERROR_NOT_ENOUGH_MEMORY;
760
761 /* simply forward the request to that routine */
762 // FIXME : if results of ReadFile() have MBCS string, some data might be lost on next call.
763 dwResult = HMDeviceConsoleInClass::ReadFile(pHMHandleData,
764 lpstrAscii,
765 cchToRead * sizeof( WCHAR ),
766 lpcchRead,
767 NULL, NULL);
768
769 /* Ascii -> unicode translation */
770 if (dwResult == TRUE)
771 *lpcchRead = MultiByteToWideChar( GetConsoleCP(), 0, lpstrAscii, *lpcchRead, ( LPWSTR )lpvBuffer, cchToRead );
772
773 HEAP_free(lpstrAscii);
774
775 return (dwResult); /* deliver return code */
776}
777
778
779/*****************************************************************************
780 * Name : DWORD HMDeviceConsoleInClass::ReadConsoleInputA
781 * Purpose : read events placed in the console input queue
782 * Parameters: PHMHANDLEDATA pHMHandleData - current handle data
783 * PINPUT_RECORD pirBuffer - target buffer for events
784 * DWORD cInRecords - number of input records
785 * LPDWORD lpcRead - returns number of events stored
786 * Variables :
787 * Result : TRUE if successful, FALSE otherwise
788 * Remark :
789 * Status : UNTESTED
790 *
791 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
792 *****************************************************************************/
793
794DWORD HMDeviceConsoleInClass::ReadConsoleInputA(PHMHANDLEDATA pHMHandleData,
795 PINPUT_RECORD pirBuffer,
796 DWORD cInRecords,
797 LPDWORD lpcRead)
798{
799 ULONG ulPostCounter; /* semaphore post counter - ignored */
800 APIRET rc; /* API returncode */
801
802#ifdef DEBUG_LOCAL2
803 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::ReadConsoleInputA(%08x,%08x,%08x,%08x).\n",
804 pHMHandleData,
805 pirBuffer,
806 cInRecords,
807 lpcRead);
808#endif
809
810 iConsoleInputQueryEvents(pConsoleInput, QUERY_EVENT_WAIT);
811
812 /* now read events into target buffer */
813 for (ulPostCounter = 0;
814 ulPostCounter < cInRecords;
815 ulPostCounter++,
816 pirBuffer++)
817 {
818 rc = iConsoleInputEventPop(pirBuffer); /* get event from queue */
819 if (rc != NO_ERROR) /* if read error occurs, break look */
820 break;
821 }
822
823 *lpcRead = ulPostCounter; /* return number of records read */
824 return (TRUE); /* OK */
825}
826
827
828/*****************************************************************************
829 * Name : DWORD HMDeviceConsoleInClass::ReadConsoleInputW
830 * Purpose : read events placed in the console input queue
831 * Parameters: PHMHANDLEDATA pHMHandleData - current handle data
832 * PINPUT_RECORD pirBuffer - target buffer for events
833 * DWORD cInRecords - number of input records
834 * LPDWORD lpcRead - returns number of events stored
835 * Variables :
836 * Result : TRUE if successful, FALSE otherwise
837 * Remark :
838 * Status : UNTESTED
839 *
840 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
841 *****************************************************************************/
842
843DWORD HMDeviceConsoleInClass::ReadConsoleInputW(PHMHANDLEDATA pHMHandleData,
844 PINPUT_RECORD pirBuffer,
845 DWORD cInRecords,
846 LPDWORD lpcRead)
847{
848 ULONG ulPostCounter; /* semaphore post counter - ignored */
849 APIRET rc; /* API returncode */
850
851#ifdef DEBUG_LOCAL2
852 WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::ReadConsoleInputW(%08x,%08x,%08x,%08x).\n",
853 pHMHandleData,
854 pirBuffer,
855 cInRecords,
856 lpcRead);
857#endif
858
859 iConsoleInputQueryEvents(pConsoleInput, QUERY_EVENT_WAIT);
860
861 /* now read events into target buffer */
862 for (ulPostCounter = 0;
863 ulPostCounter < cInRecords;
864 ulPostCounter++,
865 pirBuffer++)
866 {
867 rc = iConsoleInputEventPop(pirBuffer); /* get event from queue */
868 if (rc != NO_ERROR) /* if read error occurs, break look */
869 break;
870 }
871
872 *lpcRead = ulPostCounter; /* return number of records read */
873 return (TRUE); /* OK */
874}
875
876
877/*****************************************************************************
878 * Name : DWORD HMDeviceConsoleInClass::SetConsoleMode
879 * Purpose : sets the current console mode
880 * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
881 * DWORD dwMode - console mode
882 * Variables :
883 * Result :
884 * Remark :
885 * Status : UNTESTED
886 *
887 * Author : Patrick Haller [Wed, 1998/02/16 11:46]
888 *****************************************************************************/
889
890DWORD HMDeviceConsoleInClass::SetConsoleMode(PHMHANDLEDATA pHMHandleData,
891 DWORD dwMode)
892{
893 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
894
895#ifdef DEBUG_LOCAL2
896 WriteLog("KERNEL32/CONSOLE: CONIN$::SetConsoleMode(%08x,%08x).\n",
897 pHMHandleData,
898 dwMode);
899#endif
900
901 pConsoleInput->dwConsoleMode = dwMode; /* set current console mode */
902
903 return (TRUE);
904}
905
906
907/*****************************************************************************
908 * Name : DWORD HMDeviceConsoleInClass::WriteConsoleInputA
909 * Purpose : this writes event records directly into the queue
910 * Parameters: PHMHANDLEDATA pHMHandleData
911 * PINPUT_RECORD pirBuffer
912 * DWORD cInRecords
913 * LPDWORD lpcWritten
914 * Variables :
915 * Result :
916 * Remark :
917 * Status : NO_ERROR - API succeeded
918 * other - what is to be set in SetLastError
919 *
920 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
921 *****************************************************************************/
922
923DWORD HMDeviceConsoleInClass::WriteConsoleInputA (PHMHANDLEDATA pHMHandleData,
924 PINPUT_RECORD pirBuffer,
925 DWORD cInRecords,
926 LPDWORD lpcWritten)
927{
928 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
929 APIRET rc; /* API returncode */
930 ULONG ulCounter; /* loop counter */
931
932#ifdef DEBUG_LOCAL2
933 WriteLog("KERNEL32/CONSOLE: CONIN$::WriteConsoleInputA(%08x,%08x,%u,%08x).\n",
934 pHMHandleData,
935 pirBuffer,
936 cInRecords,
937 lpcWritten);
938#endif
939
940 for (ulCounter = 0;
941 ulCounter < cInRecords;
942 ulCounter++,
943 pirBuffer++)
944 {
945 rc = iConsoleInputEventPush(pirBuffer); /* push current event */
946 if (rc != NO_ERROR) /* oops ? queue full ? problem ? */
947 break;
948 }
949
950 *lpcWritten = ulCounter; /* return number of events written */
951 return (TRUE); /* OK */
952}
953
954
955/*****************************************************************************
956 * Name : DWORD HMDeviceConsoleInClass::WriteConsoleInputW
957 * Purpose : this writes event records directly into the queue
958 * Parameters: PHMHANDLEDATA pHMHandleData
959 * PINPUT_RECORD pirBuffer
960 * DWORD cInRecords
961 * LPDWORD lpcWritten
962 * Variables :
963 * Result :
964 * Remark :
965 * Status : NO_ERROR - API succeeded
966 * other - what is to be set in SetLastError
967 *
968 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
969 *****************************************************************************/
970
971DWORD HMDeviceConsoleInClass::WriteConsoleInputW (PHMHANDLEDATA pHMHandleData,
972 PINPUT_RECORD pirBuffer,
973 DWORD cInRecords,
974 LPDWORD lpcWritten)
975{
976 PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
977 APIRET rc; /* API returncode */
978 ULONG ulCounter; /* loop counter */
979
980#ifdef DEBUG_LOCAL2
981 WriteLog("KERNEL32/CONSOLE: CONIN$::WriteConsoleInputW(%08x,%08x,%u,%08x).\n",
982 pHMHandleData,
983 pirBuffer,
984 cInRecords,
985 lpcWritten);
986#endif
987
988 for (ulCounter = 0;
989 ulCounter < cInRecords;
990 ulCounter++,
991 pirBuffer++)
992 {
993 rc = iConsoleInputEventPush(pirBuffer); /* push current event */
994 if (rc != NO_ERROR) /* oops ? queue full ? problem ? */
995 break;
996 }
997
998 *lpcWritten = ulCounter; /* return number of events written */
999 return (TRUE); /* OK */
1000}
1001
1002
Note: See TracBrowser for help on using the repository browser.