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

Last change on this file since 3976 was 3976, checked in by phaller, 25 years ago

.

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