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

Last change on this file since 2802 was 2802, checked in by sandervl, 26 years ago

Added new logging feature

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