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

Last change on this file since 10471 was 10471, checked in by sandervl, 17 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.