Ignore:
Timestamp:
Jun 17, 1999, 8:22:43 PM (26 years ago)
Author:
phaller
Message:

Fix: major restructuring of Open32 handle management, HandleManager

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/console.cpp

    r100 r111  
    1 /* $Id: console.cpp,v 1.5 1999-06-10 20:47:55 phaller Exp $ */
     1/* $Id: console.cpp,v 1.6 1999-06-17 18:21:39 phaller Exp $ */
    22
    33/*
     
    6464#include <os2.h>
    6565#include <builtin.h>
    66 
    6766#include <stdlib.h>
    6867#include <string.h>
    69 #include "win32type.h"
    70 #include "misc.h"
     68
     69#include <win32type.h>
     70#include <misc.h>
     71
     72#include "conwin.h"          // Windows Header for console only
     73#include "HandleManager.h"
     74#include "HMDevice.h"
     75
    7176#include "console.h"
    7277#include "console2.h"
     78#include "conin.h"
     79#include "conout.h"
     80#include "conbuffer.h"
     81
    7382#include "conprop.h"
    7483#include "unicode.h"
    75 #include "HandleManager.h"
    7684
    7785
     
    97105    _O32_SetLastError(a);
    98106    SetFS(sel);
    99 } 
     107}
    100108
    101109inline DWORD GetLastError()
     
    108116
    109117    return yyrc;
    110 } 
     118}
    111119
    112120inline LPSTR GetCommandLine()
     
    119127
    120128    return yyrc;
    121 } 
     129}
    122130
    123131inline void ExitProcess(UINT a)
     
    127135    _O32_ExitProcess(a);
    128136    SetFS(sel);
    129 } 
     137}
    130138
    131139inline HANDLE GetStdHandle(DWORD a)
     
    138146
    139147    return yyrc;
    140 } 
     148}
    141149
    142150inline DWORD GetFileType(HANDLE a)
     
    149157
    150158    return yyrc;
    151 }
    152 
    153 }
    154 
    155 #define INVALID_HANDLE_VALUE ((HANDLE)-1)
    156 #define STD_INPUT_HANDLE         ((DWORD)-10)
    157 #define STD_OUTPUT_HANDLE        ((DWORD)-11)
    158 #define STD_ERROR_HANDLE         ((DWORD)-12)
    159 #define GENERIC_READ                 0x80000000
    160 #define GENERIC_WRITE                0x40000000
    161 #define FILE_SHARE_READ              0x00000001
    162 #define FILE_SHARE_WRITE             0x00000002
    163 
    164 
     159}
     160
     161}
    165162
    166163/*****************************************************************************
     
    168165 *****************************************************************************/
    169166
    170 #define SZ_CONSOLE_CLASS "WIN32CONSOLECLASS"
    171 
    172 
    173 /* according to the updated AVIO documentation of Warp 4 */
    174 #define MAX_OS2_ROWS           255
    175 #define MAX_OS2_COLUMNS        255
    176 #define FORMAT_CGA             1
    177 #define CONSOLE_TIMER_ID       1
    178 #define CONSOLE_INPUTQUEUESIZE 256
    179 
    180 
    181 #define CONSOLECURSOR_HIDE         1
    182 #define CONSOLECURSOR_SHOW         2
    183 #define CONSOLECURSOR_BLINK        3
    184 #define CONSOLECURSOR_OVERWRITTEN  4
    185 
    186 #define UM_CONSOLE_CREATE WM_USER + 0x1000
    187 
    188 
    189 /* device request codes for use in the pseudo-device handlers */
    190 #define DRQ_CONSOLE                        0x00010000
    191 #define DRQ_FILLCONSOLEOUTPUTATTRIBUTE     DRQ_CONSOLE +  0
    192 #define DRQ_FILLCONSOLEOUTPUTCHARACTERA    DRQ_CONSOLE +  1
    193 #define DRQ_FILLCONSOLEOUTPUTCHARACTERW    DRQ_CONSOLE +  2
    194 #define DRQ_FLUSHCONSOLEINPUTBUFFER        DRQ_CONSOLE +  3
    195 #define DRQ_GETCONSOLECURSORINFO           DRQ_CONSOLE +  4
    196 #define DRQ_GETCONSOLEMODE                 DRQ_CONSOLE +  5
    197 #define DRQ_GETCONSOLESCREENBUFFERINFO     DRQ_CONSOLE +  6
    198 #define DRQ_GETLARGESTCONSOLEWINDOWSIZE    DRQ_CONSOLE +  7
    199 #define DRQ_GETNUMBEROFCONSOLEINPUTEVENTS  DRQ_CONSOLE +  8
    200 #define DRQ_PEEKCONSOLEINPUTW              DRQ_CONSOLE +  9
    201 #define DRQ_PEEKCONSOLEINPUTA              DRQ_CONSOLE + 10
    202 #define DRQ_READCONSOLEA                   DRQ_CONSOLE + 11
    203 #define DRQ_READCONSOLEW                   DRQ_CONSOLE + 12
    204 #define DRQ_READCONSOLEINPUTA              DRQ_CONSOLE + 14
    205 #define DRQ_READCONSOLEINPUTW              DRQ_CONSOLE + 15
    206 #define DRQ_READCONSOLEOUTPUTA             DRQ_CONSOLE + 16
    207 #define DRQ_READCONSOLEOUTPUTW             DRQ_CONSOLE + 17
    208 #define DRQ_READCONSOLEOUTPUTATTRIBUTE     DRQ_CONSOLE + 18
    209 #define DRQ_READCONSOLEOUTPUTCHARACTERA    DRQ_CONSOLE + 19
    210 #define DRQ_READCONSOLEOUTPUTCHARACTERW    DRQ_CONSOLE + 20
    211 #define DRQ_SCROLLCONSOLESCREENBUFFERA     DRQ_CONSOLE + 21
    212 #define DRQ_SCROLLCONSOLESCREENBUFFERW     DRQ_CONSOLE + 22
    213 #define DRQ_SETCONSOLEACTIVESCREENBUFFER   DRQ_CONSOLE + 23
    214 #define DRQ_SETCONSOLECURSORINFO           DRQ_CONSOLE + 24
    215 #define DRQ_SETCONSOLECURSORPOSITION       DRQ_CONSOLE + 25
    216 #define DRQ_SETCONSOLEMODE                 DRQ_CONSOLE + 26
    217 #define DRQ_SETCONSOLESCREENBUFFERSIZE     DRQ_CONSOLE + 27
    218 #define DRQ_SETCONSOLETEXTATTRIBUTE        DRQ_CONSOLE + 28
    219 #define DRQ_SETCONSOLEWINDOWINFO           DRQ_CONSOLE + 29
    220 #define DRQ_WRITECONSOLEA                  DRQ_CONSOLE + 30
    221 #define DRQ_WRITECONSOLEW                  DRQ_CONSOLE + 31
    222 #define DRQ_WRITECONSOLEINPUTA             DRQ_CONSOLE + 32
    223 #define DRQ_WRITECONSOLEINPUTW             DRQ_CONSOLE + 33
    224 #define DRQ_WRITECONSOLEOUTPUTA            DRQ_CONSOLE + 34
    225 #define DRQ_WRITECONSOLEOUTPUTW            DRQ_CONSOLE + 35
    226 #define DRQ_WRITECONSOLEOUTPUTATTRIBUTE    DRQ_CONSOLE + 36
    227 #define DRQ_WRITECONSOLEOUTPUTCHARACTERA   DRQ_CONSOLE + 37
    228 #define DRQ_WRITECONSOLEOUTPUTCHARACTERW   DRQ_CONSOLE + 38
    229 #define DRQ_INTERNAL_CONSOLEBUFFERMAP      DRQ_CONSOLE + 39
    230 #define DRQ_INTERNAL_CONSOLECURSORSHOW     DRQ_CONSOLE + 40
    231 #define DRQ_INTERNAL_CONSOLEADJUSTWINDOW   DRQ_CONSOLE + 41
    232 
    233 
    234 #define COORD2ULONG(c) ((ULONG)( ((ULONG)c.X << 16) + (ULONG)c.Y))
    235 #define ULONG2COORD(c,u) c.X = u >> 16; c.Y = u & 0x0000FFFF;
    236 
    237 
    238167/*****************************************************************************
    239168 * Structures                                                                *
     
    242171
    243172/*****************************************************************************
    244  * Local Prototypes                                                          *
    245  *****************************************************************************/
    246 
    247 
    248 static APIRET ConsoleTerminate(void);/* termination of the console subsystem */
    249 
    250                                                    /* console message thread */
    251 static VOID _Optlink ConsoleMsgThread    (void *pParameters);
    252 
    253 static MRESULT EXPENTRY ConsoleWindowProc(HWND   hwnd,   /* window procedure */
    254                                           ULONG  msg,
    255                                           MPARAM mp1,
    256                                           MPARAM mp2);
    257 
    258 static MRESULT EXPENTRY ConsoleFrameWindowProc(HWND   hwnd,
    259                                                ULONG  msg,
    260                                                MPARAM mp1,
    261                                                MPARAM mp2);
    262 
    263 static void   ConsoleBufferMap           (PCONSOLEBUFFER pConsoleBuffer);
    264 
    265 static void   ConsoleBufferScrollUp      (PCONSOLEBUFFER pConsoleBuffer,
    266                                           ULONG          ulLines);
    267 
    268 static void   ConsoleBufferFillLine      (ULONG   ulPattern,
    269                                           PUSHORT pusTarget,
    270                                           ULONG   ulSize);
    271 
    272 static APIRET ConsoleInputEventPush      (PINPUT_RECORD pInputRecord);
    273 
    274 static APIRET ConsoleInputEventPop       (PINPUT_RECORD pInputRecord);
    275 
    276 static APIRET ConsoleInputEventPushKey   (MPARAM mp1,
    277                                           MPARAM mp2);
    278 
    279 static APIRET ConsoleInputEventPushMouse (ULONG  ulMessage,
    280                                           MPARAM mp1,
    281                                           MPARAM mp2);
    282 
    283 static APIRET ConsoleInputEventPushWindow(COORD coordWindowSize);
    284 
    285 static APIRET ConsoleInputEventPushMenu  (DWORD dwCommandId);
    286 
    287 static APIRET ConsoleInputEventPushFocus (BOOL bSetFocus);
    288 
    289 static ULONG  ConsoleInputQueryEvents    (void);
    290 
    291 static void   ConsoleCursorShow          (PCONSOLEBUFFER pConsoleBuffer,
    292                                           ULONG          ulCursorMode);
    293 
    294 static APIRET ConsoleFontQuery           (void);
    295 
    296 static void   ConsoleAdjustWindow        (PCONSOLEBUFFER pConsoleBuffer);
    297 
    298 
    299 /*****************************************************************************
    300173 * Process Global Structures                                                 *
    301174 *****************************************************************************/
    302175
    303 
    304 struct _ConsoleGlobals
    305 {
    306   public:
    307     TID    tidConsole;                             /* console message thread */
    308     HEV    hevConsole;                            /* console event semaphore */
    309     APIRET rcConsole;                /* initialization status of the console */
    310     HAB    hab;                                       /* anchor block handle */
    311     HMQ    hmq;               /* message queue handle for the console window */
    312     QMSG   qmsg;                           /* message for the console window */
    313     ULONG  flFrameFlags;                      /* frame window creation flags */
    314     PSZ    pszWindowTitle;                             /* name of the window */
    315     HWND   hwndFrame;                                 /* frame window handle */
    316     HWND   hwndClient;                               /* client window handle */
    317 
    318     HWND   hwndHorzScroll;                /* handle of horizontal scroll bar */
    319     HWND   hwndVertScroll;                  /* handle of vertical scroll bar */
    320     BOOL   fHasVertScroll;            /* indicates if scrollbars are visible */
    321     BOOL   fHasHorzScroll;
    322 
    323     HDC    hdcConsole;                             /* console device context */
    324     PFNWP  pfnwpFrameOriginal;            /* original frame window procedure */
    325 
    326     HWND     hwndMenuConsole;                          /* console popup menu */
    327     HMODULE  hmodResource;           /* resources are stored in KERNEL32.DLL */
    328     HPOINTER hPtrConsole;                                    /* console icon */
    329 
    330     HANDLE hConsoleBuffer;            /* handle of the active console buffer */
    331     HANDLE hConsoleBufferDefault;    /* handle of the default console buffer */
    332 
    333     HVPS   hvpsConsole;                   /* console AVIO presentation space */
    334 
    335     COORD  coordMaxWindowPels;              /* maximum window size in pixels */
    336     COORD  coordWindowSize;                   /* current console window size */
    337     COORD  coordWindowPos;                           /* scroller's positions */
    338 
    339     SHORT  sCellCX; /* height and width of a avio cell with the current font */
    340     SHORT  sCellCY;
    341 
    342     BOOL   fUpdateRequired; /* set to TRUE if next WM_TIMER shall update the */
    343                            /* AVIO presentation space from the consolebuffer */
    344 
    345     ULONG  idTimer;                                      /* Timer identifier */
    346     ULONG  ulTimerFrequency;             /* cursor + blitter timer frequency */
    347     ULONG  ulTimerCursor;                 /* cursor loop counter for divisor */
    348 
    349     CONSOLEOPTIONS Options;            /* the console's options / properties */
    350 
    351 } ConsoleGlobals;
    352 
    353 
    354 struct _ConsoleInput
    355 {
    356   INPUT_RECORD arrInputRecord[CONSOLE_INPUTQUEUESIZE];       /* packet queue */
    357   HEV          hevInputQueue;             /* becomes posted if input arrives */
    358 
    359   /* HMUTEX hmtxInputQueue; if queue corruption should occur ... */
    360 
    361   ULONG        ulIndexFree;              /* index of first free event record */
    362   ULONG        ulIndexEvent;          /* index of first valid event in queue */
    363   ULONG        ulEvents;                        /* number of events in queue */
    364   DWORD        dwConsoleMode;                          /* input console mode */
    365 } ConsoleInput;
     176static ICONSOLEGLOBALS ConsoleGlobals;
     177static ICONSOLEINPUT   ConsoleInput;
    366178
    367179
     
    383195 *****************************************************************************/
    384196
    385 APIRET ConsoleInit(void)                /* creation of the console subsystem */
     197APIRET iConsoleInit(void)               /* creation of the console subsystem */
    386198{
    387199  APIRET rc;                                              /* API return code */
     
    418230   ***************************************************************************/
    419231
    420   rc = ConsoleDevicesRegister();                 /* ensure devices are there */
     232  rc = iConsoleDevicesRegister();                /* ensure devices are there */
    421233  if (rc != NO_ERROR)                                    /* check for errors */
    422234  {
     
    433245    /* OK, we're about to initialize the console subsystem for this process. */
    434246                           /* start message thread for console object window */
    435   ConsoleGlobals.tidConsole = _beginthread(ConsoleMsgThread,
     247  ConsoleGlobals.tidConsole = _beginthread(iConsoleMsgThread,
    436248                                           NULL,
    437                                            16384,
     249                                           12288,
    438250                                           NULL);
    439251                                   /* has the thread been created properly ? */
     
    486298 *****************************************************************************/
    487299
    488 APIRET ConsoleDevicesRegister(void)
     300APIRET iConsoleDevicesRegister(void)
    489301{
    490302  DWORD  dwType;                                       /* device handle type */
     
    580392                   /* create devices and register devices with handlemanager */
    581393
    582     pHMDeviceConsoleIn  = new HMDeviceConsoleInClass("CONIN$");
     394    pHMDeviceConsoleIn  = new HMDeviceConsoleInClass("CONIN$",
     395                                                     &ConsoleInput,
     396                                                     &ConsoleGlobals);
    583397    rc = HMDeviceRegister ("CONIN$",
    584398                           pHMDeviceConsoleIn);
     
    588402
    589403
    590     pHMDeviceConsoleOut = new HMDeviceConsoleOutClass("CONOUT$");
     404    pHMDeviceConsoleOut = new HMDeviceConsoleOutClass("CONOUT$",
     405                                                      &ConsoleInput,
     406                                                      &ConsoleGlobals);
    591407    rc = HMDeviceRegister ("CONOUT$",
    592408                           pHMDeviceConsoleOut);
     
    596412
    597413
    598     pHMDeviceConsoleBuffer = new HMDeviceConsoleBufferClass("CONBUFFER$");
     414    pHMDeviceConsoleBuffer = new HMDeviceConsoleBufferClass("CONBUFFER$",
     415                                                            &ConsoleInput,
     416                                                            &ConsoleGlobals);
    599417    rc = HMDeviceRegister ("CONBUFFER$",
    600418                           pHMDeviceConsoleBuffer);
     
    675493 *****************************************************************************/
    676494
    677 static APIRET ConsoleTerminate(VOID)
     495APIRET iConsoleTerminate(VOID)
    678496{
    679497  APIRET rc;
     
    707525 *****************************************************************************/
    708526
    709 void ConsoleWaitClose(void)
     527void iConsoleWaitClose(void)
    710528{
    711529  CHAR szBuffer[128];                                /* buffer for the title */
     
    713531
    714532                                /* check if there is a console window at all */
    715   if (ConsoleIsActive() == FALSE)
     533  if (iConsoleIsActive() == FALSE)
    716534    return;                                                          /* nope */
    717535
     
    745563 *****************************************************************************/
    746564
    747 BOOL ConsoleIsActive(void)
     565BOOL iConsoleIsActive(void)
    748566{
    749567  return (NULLHANDLE != ConsoleGlobals.hevConsole);
     
    763581 *****************************************************************************/
    764582
    765 static VOID ConsoleMsgThread(PVOID pParameters)
     583VOID iConsoleMsgThread(PVOID pParameters)
    766584{
    767585  APIRET rc;                                              /* API return code */
     
    787605      if (WinRegisterClass(ConsoleGlobals.hab, /* register our class with PM */
    788606                           SZ_CONSOLE_CLASS,
    789                            ConsoleWindowProc,
     607                           iConsoleWindowProc,
    790608                           CS_SIZEREDRAW,
    791609                           0)
     
    870688 *****************************************************************************/
    871689
    872 static MRESULT EXPENTRY ConsoleWindowProc(HWND   hwnd,
    873                                           ULONG  msg,
    874                                           MPARAM mp1,
    875                                           MPARAM mp2)
     690MRESULT EXPENTRY iConsoleWindowProc(HWND   hwnd,
     691                                    ULONG  msg,
     692                                    MPARAM mp1,
     693                                    MPARAM mp2)
    876694{
    877695  static RECTL rcl;                                      /* window rectangle */
     
    900718      hwndFrame = ConsoleGlobals.hwndFrame;
    901719      ConsoleGlobals.pfnwpFrameOriginal = WinSubclassWindow(hwndFrame,
    902                                                             ConsoleFrameWindowProc);
     720                                                            iConsoleFrameWindowProc);
    903721
    904722      ConsoleGlobals.hwndMenuConsole
     
    958776                 rc);
    959777
    960       ConsoleFontQuery();                        /* query current cell sizes */
     778      iConsoleFontQuery();                       /* query current cell sizes */
    961779
    962780                                          /* adjust window size and position */
     
    12221040
    12231041    case WM_CHAR:
    1224       ConsoleInputEventPushKey(mp1,                 /* push event into queue */
    1225                                mp2);
     1042      iConsoleInputEventPushKey(mp1,                /* push event into queue */
     1043                                mp2);
    12261044      break;                                  /* enable further processing ! */
    12271045
     
    12321050
    12331051    case WM_SETFOCUS:
    1234       ConsoleInputEventPushFocus((BOOL)mp2);        /* push event into queue */
     1052      iConsoleInputEventPushFocus((BOOL)mp2);       /* push event into queue */
    12351053      break;                                  /* enable further processing ! */
    12361054
     
    12501068    case WM_BUTTON2DBLCLK:
    12511069    case WM_BUTTON3DBLCLK:
    1252       ConsoleInputEventPushMouse(msg,
    1253                                  mp1,               /* push event into queue */
    1254                                  mp2);
     1070      iConsoleInputEventPushMouse(msg,
     1071                                  mp1,              /* push event into queue */
     1072                                  mp2);
    12551073      break;                                  /* enable further processing ! */
    12561074  }
     
    12781096 *****************************************************************************/
    12791097
    1280 static MRESULT EXPENTRY ConsoleFrameWindowProc(HWND   hwnd,
    1281                                                ULONG  msg,
    1282                                                MPARAM mp1,
    1283                                                MPARAM mp2)
     1098MRESULT EXPENTRY iConsoleFrameWindowProc(HWND   hwnd,
     1099                                         ULONG  msg,
     1100                                         MPARAM mp1,
     1101                                         MPARAM mp2)
    12841102{
    12851103  switch(msg)
     
    13311149 *****************************************************************************/
    13321150
    1333 static void ConsoleBufferMap(PCONSOLEBUFFER pConsoleBuffer)
     1151void iConsoleBufferMap(PCONSOLEBUFFER pConsoleBuffer)
    13341152{
    13351153  ULONG ulLine;
     
    13741192 *****************************************************************************/
    13751193
    1376 static void ConsoleBufferFillLine(ULONG   ulPattern,
    1377                                   PUSHORT pusTarget,
    1378                                   ULONG   ulSize)
     1194void iConsoleBufferFillLine(ULONG   ulPattern,
     1195                            PUSHORT pusTarget,
     1196                            ULONG   ulSize)
    13791197{
    13801198  ULONG  ulCounter;
     
    14051223 *****************************************************************************/
    14061224
    1407 static void ConsoleBufferScrollUp(PCONSOLEBUFFER pConsoleBuffer,
    1408                                   ULONG          ulLines)
     1225void iConsoleBufferScrollUp(PCONSOLEBUFFER pConsoleBuffer,
     1226                            ULONG          ulLines)
    14091227{
    14101228  ULONG ulLine;
     
    14491267       ulLine < pConsoleBuffer->coordBufferSize.Y;
    14501268       ulLine++)
    1451     ConsoleBufferFillLine(ulPosition,
    1452                           (PUSHORT)(pConsoleBuffer->ppszLine[ulLine]),
    1453                           pConsoleBuffer->coordBufferSize.X);
     1269    iConsoleBufferFillLine(ulPosition,
     1270                           (PUSHORT)(pConsoleBuffer->ppszLine[ulLine]),
     1271                           pConsoleBuffer->coordBufferSize.X);
    14541272
    14551273    /* this code ensures frequent screen updating, even if the timer prooves */
     
    14591277  {
    14601278    ulUpdateCounter = 0;                                /* reset the counter */
    1461     ConsoleBufferMap(pConsoleBuffer);
     1279    iConsoleBufferMap(pConsoleBuffer);
    14621280    VioShowPS(ConsoleGlobals.coordWindowSize.Y,
    14631281              ConsoleGlobals.coordWindowSize.X,
     
    14811299 *****************************************************************************/
    14821300
    1483 static APIRET ConsoleInputEventPush(PINPUT_RECORD pInputRecord)
     1301APIRET iConsoleInputEventPush(PINPUT_RECORD pInputRecord)
    14841302{
    14851303  PINPUT_RECORD pirFree;                           /* pointer to free record */
     
    15241342 *****************************************************************************/
    15251343
    1526 static APIRET ConsoleInputEventPop(PINPUT_RECORD pInputRecord)
     1344APIRET iConsoleInputEventPop(PINPUT_RECORD pInputRecord)
    15271345{
    15281346  PINPUT_RECORD pirEvent;                         /* pointer to event record */
     
    17251543
    17261544
    1727 static APIRET ConsoleInputEventPushKey(MPARAM mp1,
    1728                                        MPARAM mp2)
     1545APIRET iConsoleInputEventPushKey(MPARAM mp1,
     1546                                 MPARAM mp2)
    17291547{
    17301548  INPUT_RECORD InputRecord;                    /* the input record structure */
     
    18311649#endif
    18321650
    1833   rc = ConsoleInputEventPush(&InputRecord);           /* add it to the queue */
     1651  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
    18341652  return (rc);                                                         /* OK */
    18351653}
     
    18481666 *****************************************************************************/
    18491667
    1850 static APIRET ConsoleInputEventPushMouse(ULONG  ulMessage,
    1851                                          MPARAM mp1,
    1852                                          MPARAM mp2)
     1668APIRET iConsoleInputEventPushMouse(ULONG  ulMessage,
     1669                                   MPARAM mp1,
     1670                                   MPARAM mp2)
    18531671{
    18541672  INPUT_RECORD     InputRecord;                /* the input record structure */
     
    19471765    InputRecord.Event.MouseEvent.dwButtonState |= RIGHTMOST_BUTTON_PRESSED;
    19481766
    1949   rc = ConsoleInputEventPush(&InputRecord);           /* add it to the queue */
     1767  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
    19501768  return (rc);                                                         /* OK */
    19511769}
     
    19641782 *****************************************************************************/
    19651783
    1966 static APIRET ConsoleInputEventPushWindow(COORD coordWindowSize)
     1784APIRET iConsoleInputEventPushWindow(COORD coordWindowSize)
    19671785{
    19681786  INPUT_RECORD     InputRecord;                /* the input record structure */
     
    19811799  InputRecord.Event.WindowBufferSizeEvent.dwSize = coordWindowSize;
    19821800
    1983   rc = ConsoleInputEventPush(&InputRecord);           /* add it to the queue */
     1801  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
    19841802  return (rc);                                                         /* OK */
    19851803}
     
    19981816 *****************************************************************************/
    19991817
    2000 static APIRET ConsoleInputEventPushMenu(DWORD dwCommandId)
     1818APIRET iConsoleInputEventPushMenu(DWORD dwCommandId)
    20011819{
    20021820  INPUT_RECORD     InputRecord;                /* the input record structure */
     
    20151833  InputRecord.Event.MenuEvent.dwCommandId = dwCommandId;
    20161834
    2017   rc = ConsoleInputEventPush(&InputRecord);           /* add it to the queue */
     1835  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
    20181836  return (rc);                                                         /* OK */
    20191837}
     
    20321850 *****************************************************************************/
    20331851
    2034 static APIRET ConsoleInputEventPushFocus(BOOL bSetFocus)
     1852APIRET iConsoleInputEventPushFocus(BOOL bSetFocus)
    20351853{
    20361854  INPUT_RECORD     InputRecord;                /* the input record structure */
     
    20491867  InputRecord.Event.FocusEvent.bSetFocus = bSetFocus;
    20501868
    2051   rc = ConsoleInputEventPush(&InputRecord);           /* add it to the queue */
     1869  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
    20521870  return (rc);                                                         /* OK */
    20531871}
     
    20661884 *****************************************************************************/
    20671885
    2068 static ULONG ConsoleInputQueryEvents (void)
     1886ULONG iConsoleInputQueryEvents (void)
    20691887{
    20701888  return (ConsoleInput.ulEvents);        /* return number of events in queue */
     
    20841902 *****************************************************************************/
    20851903
    2086 static void ConsoleCursorShow (PCONSOLEBUFFER pConsoleBuffer,
    2087                                ULONG          ulCursorMode)
     1904void iConsoleCursorShow (PCONSOLEBUFFER pConsoleBuffer,
     1905                         ULONG          ulCursorMode)
    20881906{
    20891907  HPS   hps;                                    /* presentation space handle */
     
    21621980 *****************************************************************************/
    21631981
    2164 static APIRET ConsoleFontQuery (void)
     1982APIRET iConsoleFontQuery (void)
    21651983{
    21661984  return(VioGetDeviceCellSize(&ConsoleGlobals.sCellCY,  /* query VIO manager */
     
    21822000 *****************************************************************************/
    21832001
    2184 static void ConsoleAdjustWindow (PCONSOLEBUFFER pConsoleBuffer)
     2002void iConsoleAdjustWindow (PCONSOLEBUFFER pConsoleBuffer)
    21852003{
    21862004  LONG   lX, lY;                                    /* temporary long values */
     
    23682186#endif
    23692187
    2370   rc = ConsoleInit();                    /* initialize subsystem if required */
     2188  rc = iConsoleInit();                   /* initialize subsystem if required */
    23712189  if (rc != NO_ERROR)                                    /* check for errors */
    23722190  {
     
    24202238                         dwDesiredAccess,
    24212239                         dwShareMode,
    2422                          lpSecurityAttributes,
     2240                         (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
    24232241                         0,
    24242242                         dwFlags,
     
    26042422#endif
    26052423
    2606   rc = ConsoleTerminate();                /* terminate subsystem if required */
     2424  rc = iConsoleTerminate();               /* terminate subsystem if required */
    26072425  if (rc != NO_ERROR)                                    /* check for errors */
    26082426  {
     
    42004018  return fResult;
    42014019}
    4202 
    4203 
    4204 /*****************************************************************************
    4205  * Name      : DWORD HMDeviceConsoleInClass::CreateFile
    4206  * Purpose   : this is called from the handle manager if a CreateFile() is
    4207  *             performed on a handle
    4208  * Parameters: LPCSTR        lpFileName            name of the file / device
    4209  *             PHMHANDLEDATA pHMHandleData         data of the NEW handle
    4210  *             PVOID         lpSecurityAttributes  ignored
    4211  *             PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
    4212  * Variables :
    4213  * Result    :
    4214  * Remark    : @@@PH CONIN$ handles should be exclusive
    4215  *                   reject other requests to this device
    4216  * Status    : NO_ERROR - API succeeded
    4217  *             other    - what is to be set in SetLastError
    4218  *
    4219  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    4220  *****************************************************************************/
    4221 
    4222 DWORD HMDeviceConsoleInClass::CreateFile (LPCSTR        lpFileName,
    4223                                           PHMHANDLEDATA pHMHandleData,
    4224                                           PVOID         lpSecurityAttributes,
    4225                                           PHMHANDLEDATA pHMHandleDataTemplate)
    4226 {
    4227 #ifdef DEBUG_LOCAL
    4228   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
    4229            lpHMDeviceName,
    4230            lpFileName,
    4231            pHMHandleData->hHandle,
    4232            lpSecurityAttributes,
    4233            pHMHandleDataTemplate);
    4234 #endif
    4235 
    4236   pHMHandleData->dwType = FILE_TYPE_CHAR;        /* we're a character device */
    4237 
    4238   return(NO_ERROR);
    4239 }
    4240 
    4241 
    4242 /*****************************************************************************
    4243  * Name      :
    4244  * Purpose   :
    4245  * Parameters:
    4246  * Variables :
    4247  * Result    :
    4248  * Remark    :
    4249  * Status    :
    4250  *
    4251  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    4252  *****************************************************************************/
    4253 
    4254 DWORD HMDeviceConsoleInClass::ReadFile(PHMHANDLEDATA pHMHandleData,
    4255                                        LPCVOID       lpBuffer,
    4256                                        DWORD         nNumberOfBytesToRead,
    4257                                        LPDWORD       lpNumberOfBytesRead,
    4258                                        LPOVERLAPPED  lpOverlapped)
    4259 {
    4260   ULONG  ulCounter;                  /* character counter for the queue loop */
    4261   PSZ    pszTarget;                              /* pointer to target buffer */
    4262   APIRET rc;                                               /* API returncode */
    4263   INPUT_RECORD InputRecord;               /* buffer for the event to be read */
    4264   ULONG  ulPostCounter;                            /* semaphore post counter */
    4265 
    4266 #ifdef DEBUG_LOCAL
    4267   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)\n",
    4268            lpHMDeviceName,
    4269            pHMHandleData->hHandle,
    4270            lpBuffer,
    4271            nNumberOfBytesToRead,
    4272            lpNumberOfBytesRead,
    4273            lpOverlapped);
    4274 #endif
    4275 
    4276   ulCounter = 0;                              /* read ascii chars from queue */
    4277   pszTarget = (PSZ)lpBuffer;
    4278 
    4279   /* @@@PH: ConsoleMode: ENABLE_LINE_INPUT - blocks until CR is read */
    4280 
    4281                                   /* block if no key events are in the queue */
    4282   for (;ulCounter==0;)                       /* until we got some characters */
    4283   {
    4284     if (ConsoleInputQueryEvents() == 0)       /* if queue is currently empty */
    4285     {
    4286       rc = DosWaitEventSem(ConsoleInput.hevInputQueue,     /* wait for input */
    4287                            SEM_INDEFINITE_WAIT);
    4288       DosResetEventSem(ConsoleInput.hevInputQueue,        /* reset semaphore */
    4289                        &ulPostCounter);            /* post counter - ignored */
    4290     }
    4291 
    4292     do
    4293     {
    4294       rc = ConsoleInputEventPop(&InputRecord);       /* get event from queue */
    4295       if (rc == NO_ERROR)         /* if we've got a valid event in the queue */
    4296       {
    4297         if (InputRecord.EventType == KEY_EVENT)          /* check event type */
    4298         {
    4299           *pszTarget = InputRecord.Event.KeyEvent.uChar.AsciiChar;
    4300           pszTarget++;
    4301           ulCounter++;
    4302 
    4303                                                      /* local echo enabled ? */
    4304           if (ConsoleInput.dwConsoleMode & ENABLE_ECHO_INPUT)
    4305             HMWriteFile(ConsoleGlobals.hConsoleBuffer,
    4306                         &InputRecord.Event.KeyEvent.uChar.AsciiChar,
    4307                         1,
    4308                         &ulPostCounter,                      /* dummy result */
    4309                         NULL);
    4310 
    4311           if (ulCounter >= nNumberOfBytesToRead)        /* at buffer's end ? */
    4312             goto __readfile_exit;
    4313         }
    4314                                          /* Note: other events are discarded */
    4315       }
    4316     }
    4317     while (rc == NO_ERROR);
    4318   }
    4319 
    4320 __readfile_exit:
    4321 
    4322   *lpNumberOfBytesRead = ulCounter;                          /* write result */
    4323 
    4324   return(TRUE);                                                        /* OK */
    4325 }
    4326 
    4327 
    4328 /*****************************************************************************
    4329  * Name      :
    4330  * Purpose   :
    4331  * Parameters:
    4332  * Variables :
    4333  * Result    :
    4334  * Remark    :
    4335  * Status    :
    4336  *
    4337  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    4338  *****************************************************************************/
    4339 
    4340 DWORD HMDeviceConsoleInClass::WriteFile(PHMHANDLEDATA pHMHandleData,
    4341                                         LPCVOID       lpBuffer,
    4342                                         DWORD         nNumberOfBytesToWrite,
    4343                                         LPDWORD       lpNumberOfBytesWritten,
    4344                                         LPOVERLAPPED  lpOverlapped)
    4345 {
    4346 
    4347 #ifdef DEBUG_LOCAL
    4348   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass:WriteFile %s(%08x,%08x,%08x,%08x,%08x)\n",
    4349            lpHMDeviceName,
    4350            pHMHandleData->hHandle,
    4351            lpBuffer,
    4352            nNumberOfBytesToWrite,
    4353            lpNumberOfBytesWritten,
    4354            lpOverlapped);
    4355 #endif
    4356 
    4357   return(ERROR_ACCESS_DENIED);
    4358 }
    4359 
    4360 
    4361 /*****************************************************************************
    4362  * Name      :
    4363  * Purpose   :
    4364  * Parameters:
    4365  * Variables :
    4366  * Result    :
    4367  * Remark    :
    4368  * Status    :
    4369  *
    4370  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    4371  *****************************************************************************/
    4372 
    4373 DWORD  HMDeviceConsoleInClass::_DeviceRequest (PHMHANDLEDATA pHMHandleData,
    4374                                                ULONG         ulRequestCode,
    4375                                                ULONG         arg1,
    4376                                                ULONG         arg2,
    4377                                                ULONG         arg3,
    4378                                                ULONG         arg4)
    4379 {
    4380   switch (ulRequestCode)
    4381   {
    4382     case DRQ_FLUSHCONSOLEINPUTBUFFER:
    4383       return (HMDeviceConsoleInClass::
    4384               FlushConsoleInputBuffer(pHMHandleData));
    4385 
    4386     case DRQ_GETNUMBEROFCONSOLEINPUTEVENTS:
    4387       return (HMDeviceConsoleInClass::
    4388               GetNumberOfConsoleInputEvents(pHMHandleData,
    4389                                             (LPDWORD)arg1));
    4390 
    4391     case DRQ_PEEKCONSOLEINPUTA:
    4392       return (HMDeviceConsoleInClass::
    4393               PeekConsoleInputA(pHMHandleData,
    4394                                 (PINPUT_RECORD)arg1,
    4395                                 (DWORD)        arg2,
    4396                                 (LPDWORD)      arg3));
    4397 
    4398     case DRQ_PEEKCONSOLEINPUTW:
    4399       return (HMDeviceConsoleInClass::
    4400               PeekConsoleInputW(pHMHandleData,
    4401                                 (PINPUT_RECORD)arg1,
    4402                                 (DWORD)        arg2,
    4403                                 (LPDWORD)      arg3));
    4404 
    4405 
    4406     case DRQ_READCONSOLEA:
    4407       return (HMDeviceConsoleInClass::
    4408               ReadConsoleA(pHMHandleData,
    4409                            (CONST VOID*) arg1,
    4410                            (DWORD)       arg2,
    4411                            (LPDWORD)     arg3,
    4412                            (LPVOID)      arg4));
    4413 
    4414     case DRQ_READCONSOLEW:
    4415       return (HMDeviceConsoleInClass::
    4416               ReadConsoleW(pHMHandleData,
    4417                            (CONST VOID*) arg1,
    4418                            (DWORD)       arg2,
    4419                            (LPDWORD)     arg3,
    4420                            (LPVOID)      arg4));
    4421 
    4422     case DRQ_READCONSOLEINPUTA:
    4423       return (HMDeviceConsoleInClass::
    4424               ReadConsoleInputA(pHMHandleData,
    4425                                 (PINPUT_RECORD)arg1,
    4426                                 (DWORD)arg2,
    4427                                 (LPDWORD)arg3));
    4428 
    4429     case DRQ_READCONSOLEINPUTW:
    4430       return (HMDeviceConsoleInClass::
    4431               ReadConsoleInputW(pHMHandleData,
    4432                                 (PINPUT_RECORD)arg1,
    4433                                 (DWORD)arg2,
    4434                                 (LPDWORD)arg3));
    4435 
    4436     case DRQ_WRITECONSOLEINPUTA:
    4437       return (HMDeviceConsoleInClass::
    4438               WriteConsoleInputA(pHMHandleData,
    4439                                 (PINPUT_RECORD)arg1,
    4440                                 (DWORD)arg2,
    4441                                 (LPDWORD)arg3));
    4442 
    4443     case DRQ_WRITECONSOLEINPUTW:
    4444       return (HMDeviceConsoleInClass::
    4445               WriteConsoleInputW(pHMHandleData,
    4446                                 (PINPUT_RECORD)arg1,
    4447                                 (DWORD)arg2,
    4448                                 (LPDWORD)arg3));
    4449 
    4450   }
    4451 
    4452 #ifdef DEBUG_LOCAL
    4453   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleInClass:_DeviceRequest %s(%08x,%08x,%08x,%08x,%08x,%08x) unknown request\n",
    4454            lpHMDeviceName,
    4455            pHMHandleData->hHandle,
    4456            ulRequestCode,
    4457            arg1,
    4458            arg2,
    4459            arg3,
    4460            arg4);
    4461 #endif
    4462 
    4463   SetLastError(ERROR_INVALID_FUNCTION);           /* request not implemented */
    4464   return(FALSE);                 /* we assume this indicates API call failed */
    4465 }
    4466 
    4467 
    4468 /*****************************************************************************
    4469  * Name      : BOOL HMDeviceConsoleInClass::FlushConsoleInputBuffer
    4470  * Purpose   : flushes all events from the input queue
    4471  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    4472  * Variables :
    4473  * Result    :
    4474  * Remark    :
    4475  * Status    : UNTESTED
    4476  *
    4477  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    4478  *****************************************************************************/
    4479 
    4480 BOOL HMDeviceConsoleInClass::FlushConsoleInputBuffer(PHMHANDLEDATA pHMHandleData)
    4481 {
    4482   ULONG ulCounter;                                           /* loop counter */
    4483 
    4484 #ifdef DEBUG_LOCAL2
    4485   WriteLog("KERNEL32/CONSOLE: CONIN$::FlushConsoleInputBuffer(%08x).\n",
    4486            pHMHandleData);
    4487 #endif
    4488 
    4489   ConsoleInput.ulIndexFree  = 0;
    4490   ConsoleInput.ulIndexEvent = 0;
    4491   ConsoleInput.ulEvents     = 0;
    4492 
    4493   for (ulCounter = 0;
    4494        ulCounter < CONSOLE_INPUTQUEUESIZE;
    4495        ulCounter++)
    4496     ConsoleInput.arrInputRecord[ulCounter].EventType = 0x0000; /* free event */
    4497 
    4498   return (TRUE);
    4499 }
    4500 
    4501 
    4502 /*****************************************************************************
    4503  * Name      : DWORD HMDeviceConsoleInClass::GetConsoleMode
    4504  * Purpose   : queries the current console mode
    4505  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    4506  *             LPDWORD lpMode
    4507  * Variables :
    4508  * Result    :
    4509 
    4510  * Remark    :
    4511  * Status    : UNTESTED
    4512  *
    4513  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    4514  *****************************************************************************/
    4515 
    4516 DWORD HMDeviceConsoleInClass::GetConsoleMode(PHMHANDLEDATA pHMHandleData,
    4517                                              LPDWORD       lpMode)
    4518 {
    4519 #ifdef DEBUG_LOCAL2
    4520   WriteLog("KERNEL32/CONSOLE: CONIN$::GetConsoleMode(%08x,%08x).\n",
    4521            pHMHandleData,
    4522            lpMode);
    4523 #endif
    4524 
    4525   *lpMode = ConsoleInput.dwConsoleMode;       /* return current console mode */
    4526 
    4527   return (TRUE);
    4528 }
    4529 
    4530 
    4531 /*****************************************************************************
    4532  * Name      : DWORD HMDeviceConsoleInClass::GetNumberOfConsoleInputEvents
    4533  * Purpose   : queries the current number of events in the input queue
    4534  * Parameters: PHMHANDLEDATA pHMHandleData    - handle specific data
    4535  *             LPDWORD       lpNumberOfEvents - return number of events
    4536  * Variables :
    4537  * Result    :
    4538  * Remark    :
    4539  * Status    : UNTESTED
    4540  *
    4541  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    4542  *****************************************************************************/
    4543 
    4544 BOOL HMDeviceConsoleInClass::GetNumberOfConsoleInputEvents(PHMHANDLEDATA pHMHandleData,
    4545                                                            LPDWORD       lpNumberOfEvents)
    4546 {
    4547 #ifdef DEBUG_LOCAL2
    4548   WriteLog("KERNEL32/CONSOLE: CONIN$::GetNumberOfConsoleInputEvents(%08x,%08x).\n",
    4549            pHMHandleData,
    4550            lpNumberOfEvents);
    4551 #endif
    4552 
    4553   *lpNumberOfEvents = ConsoleInput.ulEvents;      /* return number of events */
    4554 
    4555   return (TRUE);
    4556 }
    4557 
    4558 
    4559 /*****************************************************************************
    4560  * Name      : DWORD HMDeviceConsoleInClass::PeekConsoleInputA
    4561  * Purpose   : peeks events placed in the console input queue
    4562  * Parameters: PHMHANDLEDATA pHMHandleData - current handle data
    4563  *             PINPUT_RECORD pirBuffer     - target buffer for events
    4564  *             DWORD         cInRecords    - number of input records
    4565  *             LPDWORD       lpcRead       - returns number of events stored
    4566  * Variables :
    4567  * Result    : TRUE if successful, FALSE otherwise
    4568  * Remark    : if queue is completely filled and no event is free,
    4569  *             loop will scan over queue multiple times, until target
    4570  *             buffer is filled. It does not check ulCounter to stop
    4571  *             when one scan of the queue is complete.
    4572  * Status    : UNTESTED
    4573  *
    4574  * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
    4575  *****************************************************************************/
    4576 
    4577 DWORD HMDeviceConsoleInClass::PeekConsoleInputA(PHMHANDLEDATA pHMHandleData,
    4578                                                 PINPUT_RECORD pirBuffer,
    4579                                                 DWORD         cInRecords,
    4580                                                 LPDWORD       lpcRead)
    4581 {
    4582   ULONG         ulCounter;                                   /* loop counter */
    4583   ULONG         ulCurrentEvent;       /* index of current event in the queue */
    4584   PINPUT_RECORD pirEvent;                /* pointer to current queue element */
    4585 
    4586 #ifdef DEBUG_LOCAL2
    4587   WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::PeekConsoleInputA(%08x,%08x,%08x,%08x).\n",
    4588            pHMHandleData,
    4589            pirBuffer,
    4590            cInRecords,
    4591            lpcRead);
    4592 #endif
    4593 
    4594   if (ConsoleInputQueryEvents() == 0)         /* if queue is currently empty */
    4595   {
    4596     *lpcRead = 0;                               /* no events read from queue */
    4597     return (TRUE);                                         /* OK, we're done */
    4598   }
    4599 
    4600 
    4601   for (ulCounter = 0,
    4602        ulCurrentEvent = ConsoleInput.ulIndexEvent,
    4603        pirEvent = &ConsoleInput.arrInputRecord[ConsoleInput.ulIndexEvent];
    4604 
    4605        ulCounter < cInRecords;
    4606 
    4607        ulCounter++,
    4608        ulCurrentEvent++,
    4609        pirEvent++,
    4610        pirBuffer++)
    4611   {
    4612     if (ulCurrentEvent > CONSOLE_INPUTQUEUESIZE) /* reaching after end of que*/
    4613     {
    4614       ulCurrentEvent = 0;         /* then start over from beginning of queue */
    4615       pirEvent       = ConsoleInput.arrInputRecord;
    4616     }
    4617 
    4618     if (pirEvent->EventType == 0x0000)                   /* no more events ? */
    4619       break;                                              /* leave loop then */
    4620 
    4621     memcpy(pirEvent,                                      /* copy event data */
    4622            pirBuffer,
    4623            sizeof(INPUT_RECORD));
    4624   }
    4625 
    4626   *lpcRead = ulCounter;                      /* return number of events read */
    4627   return (TRUE);                                           /* OK, we're done */
    4628 }
    4629 
    4630 
    4631 /*****************************************************************************
    4632  * Name      : DWORD HMDeviceConsoleInClass::PeekConsoleInputW
    4633  * Purpose   : peeks events placed in the console input queue
    4634  * Parameters: PHMHANDLEDATA pHMHandleData - current handle data
    4635  *             PINPUT_RECORD pirBuffer     - target buffer for events
    4636  *             DWORD         cInRecords    - number of input records
    4637  *             LPDWORD       lpcRead       - returns number of events stored
    4638  * Variables :
    4639  * Result    : TRUE if successful, FALSE otherwise
    4640  * Remark    : if queue is completely filled and no event is free,
    4641  *             loop will scan over queue multiple times, until target
    4642  *             buffer is filled. It does not check ulCounter to stop
    4643  *             when one scan of the queue is complete.
    4644  * Status    : UNTESTED
    4645  *
    4646  * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
    4647  *****************************************************************************/
    4648 
    4649 DWORD HMDeviceConsoleInClass::PeekConsoleInputW(PHMHANDLEDATA pHMHandleData,
    4650                                                 PINPUT_RECORD pirBuffer,
    4651                                                 DWORD         cInRecords,
    4652                                                 LPDWORD       lpcRead)
    4653 {
    4654   ULONG         ulCounter;                                   /* loop counter */
    4655   ULONG         ulCurrentEvent;       /* index of current event in the queue */
    4656   PINPUT_RECORD pirEvent;                /* pointer to current queue element */
    4657 
    4658 #ifdef DEBUG_LOCAL2
    4659   WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::PeekConsoleInputW(%08x,%08x,%08x,%08x).\n",
    4660            pHMHandleData,
    4661            pirBuffer,
    4662            cInRecords,
    4663            lpcRead);
    4664 #endif
    4665 
    4666   if (ConsoleInputQueryEvents() == 0)         /* if queue is currently empty */
    4667   {
    4668     *lpcRead = 0;                               /* no events read from queue */
    4669     return (TRUE);                                         /* OK, we're done */
    4670   }
    4671 
    4672 
    4673   for (ulCounter = 0,
    4674        ulCurrentEvent = ConsoleInput.ulIndexEvent,
    4675        pirEvent = &ConsoleInput.arrInputRecord[ConsoleInput.ulIndexEvent];
    4676 
    4677        ulCounter < cInRecords;
    4678 
    4679        ulCounter++,
    4680        ulCurrentEvent++,
    4681        pirEvent++,
    4682        pirBuffer++)
    4683   {
    4684     if (ulCurrentEvent > CONSOLE_INPUTQUEUESIZE) /* reaching after end of que*/
    4685     {
    4686       ulCurrentEvent = 0;         /* then start over from beginning of queue */
    4687       pirEvent       = ConsoleInput.arrInputRecord;
    4688     }
    4689 
    4690     if (pirEvent->EventType == 0x0000)                   /* no more events ? */
    4691       break;                                              /* leave loop then */
    4692 
    4693     memcpy(pirEvent,                                      /* copy event data */
    4694            pirBuffer,
    4695            sizeof(INPUT_RECORD));
    4696   }
    4697 
    4698   *lpcRead = ulCounter;                      /* return number of events read */
    4699   return (TRUE);                                           /* OK, we're done */
    4700 }
    4701 
    4702 
    4703 /*****************************************************************************
    4704  * Name      : DWORD HMDeviceConsoleInClass::ReadConsoleA
    4705  * Purpose   : read a string from the console
    4706  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    4707  *             LPWORD        lpwAttribute
    4708  *             DWORD         cWriteCells
    4709  *             COORD         dwWriteCoord
    4710  *             LPDWORD       lpcWritten
    4711  * Variables :
    4712  * Result    :
    4713  * Remark    :
    4714  * Status    : UNTESTED
    4715  *
    4716  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    4717  *****************************************************************************/
    4718 
    4719 DWORD HMDeviceConsoleInClass::ReadConsoleA(PHMHANDLEDATA pHMHandleData,
    4720                                            CONST VOID*   lpvBuffer,
    4721                                            DWORD         cchToRead,
    4722                                            LPDWORD       lpcchRead,
    4723                                            LPVOID        lpvReserved)
    4724 {
    4725   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    4726 
    4727 #ifdef DEBUG_LOCAL2
    4728   WriteLog("KERNEL32/CONSOLE: CONIN$::ReadConsoleA(%08x,%08x,%u,%08x,%08x).\n",
    4729            pHMHandleData,
    4730            lpvBuffer,
    4731            cchToRead,
    4732            lpcchRead,
    4733            lpvReserved);
    4734 #endif
    4735 
    4736                                /* simply forward the request to that routine */
    4737   return (HMDeviceConsoleInClass::ReadFile(pHMHandleData,
    4738                                            lpvBuffer,
    4739                                            cchToRead,
    4740                                            lpcchRead,
    4741                                            NULL));
    4742 }
    4743 
    4744 
    4745 /*****************************************************************************
    4746  * Name      : DWORD HMDeviceConsoleInClass::ReadConsoleW
    4747  * Purpose   : write a string to the console
    4748  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    4749  *             LPWORD        lpwAttribute
    4750  *             DWORD         cWriteCells
    4751  *             COORD         dwWriteCoord
    4752  *             LPDWORD       lpcWritten
    4753  * Variables :
    4754  * Result    :
    4755  * Remark    :
    4756  * Status    : UNTESTED
    4757  *
    4758  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    4759  *****************************************************************************/
    4760 
    4761 DWORD HMDeviceConsoleInClass::ReadConsoleW(PHMHANDLEDATA pHMHandleData,
    4762                                            CONST VOID*   lpvBuffer,
    4763                                            DWORD         cchToRead,
    4764                                            LPDWORD       lpcchRead,
    4765                                            LPVOID        lpvReserved)
    4766 {
    4767   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    4768   DWORD          dwResult;
    4769 
    4770 #ifdef DEBUG_LOCAL2
    4771   WriteLog("KERNEL32/CONSOLE: CONIN$::ReadConsoleW(%08x,%08x,%u,%08x,%08x).\n",
    4772            pHMHandleData,
    4773            lpvBuffer,
    4774            cchToRead,
    4775            lpcchRead,
    4776            lpvReserved);
    4777 #endif
    4778 
    4779                                /* simply forward the request to that routine */
    4780   dwResult = HMDeviceConsoleInClass::ReadFile(pHMHandleData,
    4781                                               lpvBuffer,
    4782                                               cchToRead,
    4783                                               lpcchRead,
    4784                                               NULL);
    4785   /* @@@PH AScii -> unicode translation */
    4786 
    4787   return (dwResult);                                  /* deliver return code */
    4788 }
    4789 
    4790 
    4791 /*****************************************************************************
    4792  * Name      : DWORD HMDeviceConsoleInClass::ReadConsoleInputA
    4793  * Purpose   : read events placed in the console input queue
    4794  * Parameters: PHMHANDLEDATA pHMHandleData - current handle data
    4795  *             PINPUT_RECORD pirBuffer     - target buffer for events
    4796  *             DWORD         cInRecords    - number of input records
    4797  *             LPDWORD       lpcRead       - returns number of events stored
    4798  * Variables :
    4799  * Result    : TRUE if successful, FALSE otherwise
    4800  * Remark    :
    4801  * Status    : UNTESTED
    4802  *
    4803  * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
    4804  *****************************************************************************/
    4805 
    4806 DWORD HMDeviceConsoleInClass::ReadConsoleInputA(PHMHANDLEDATA pHMHandleData,
    4807                                                 PINPUT_RECORD pirBuffer,
    4808                                                 DWORD         cInRecords,
    4809                                                 LPDWORD       lpcRead)
    4810 {
    4811   ULONG  ulPostCounter;                  /* semaphore post counter - ignored */
    4812   APIRET rc;                                               /* API returncode */
    4813 
    4814 #ifdef DEBUG_LOCAL2
    4815   WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::ReadConsoleInputA(%08x,%08x,%08x,%08x).\n",
    4816            pHMHandleData,
    4817            pirBuffer,
    4818            cInRecords,
    4819            lpcRead);
    4820 #endif
    4821 
    4822   if (ConsoleInputQueryEvents() == 0)         /* if queue is currently empty */
    4823   {
    4824     rc = DosWaitEventSem(ConsoleInput.hevInputQueue,       /* wait for input */
    4825                          SEM_INDEFINITE_WAIT);
    4826     DosResetEventSem(ConsoleInput.hevInputQueue,          /* reset semaphore */
    4827                      &ulPostCounter);              /* post counter - ignored */
    4828   }
    4829 
    4830 
    4831   /* now read events into target buffer */
    4832   for (ulPostCounter = 0;
    4833        ulPostCounter < cInRecords;
    4834        ulPostCounter++,
    4835        pirBuffer++)
    4836   {
    4837     rc = ConsoleInputEventPop(pirBuffer);            /* get event from queue */
    4838     if (rc != NO_ERROR)                  /* if read error occurs, break look */
    4839       break;
    4840   }
    4841 
    4842   *lpcRead = ulPostCounter;                 /* return number of records read */
    4843   return (TRUE);                                                       /* OK */
    4844 }
    4845 
    4846 
    4847 /*****************************************************************************
    4848  * Name      : DWORD HMDeviceConsoleInClass::ReadConsoleInputW
    4849  * Purpose   : read events placed in the console input queue
    4850  * Parameters: PHMHANDLEDATA pHMHandleData - current handle data
    4851  *             PINPUT_RECORD pirBuffer     - target buffer for events
    4852  *             DWORD         cInRecords    - number of input records
    4853  *             LPDWORD       lpcRead       - returns number of events stored
    4854  * Variables :
    4855  * Result    : TRUE if successful, FALSE otherwise
    4856  * Remark    :
    4857  * Status    : UNTESTED
    4858  *
    4859  * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
    4860  *****************************************************************************/
    4861 
    4862 DWORD HMDeviceConsoleInClass::ReadConsoleInputW(PHMHANDLEDATA pHMHandleData,
    4863                                                 PINPUT_RECORD pirBuffer,
    4864                                                 DWORD         cInRecords,
    4865                                                 LPDWORD       lpcRead)
    4866 {
    4867   ULONG ulPostCounter;                   /* semaphore post counter - ignored */
    4868   APIRET rc;                                               /* API returncode */
    4869 
    4870 #ifdef DEBUG_LOCAL2
    4871   WriteLog("KERNEL32/CONSOLE: HMDeviceConsoleInClass::ReadConsoleInputW(%08x,%08x,%08x,%08x).\n",
    4872            pHMHandleData,
    4873            pirBuffer,
    4874            cInRecords,
    4875            lpcRead);
    4876 #endif
    4877 
    4878   if (ConsoleInputQueryEvents() == 0)         /* if queue is currently empty */
    4879   {
    4880     rc = DosWaitEventSem(ConsoleInput.hevInputQueue,       /* wait for input */
    4881                          SEM_INDEFINITE_WAIT);
    4882     DosResetEventSem(ConsoleInput.hevInputQueue,          /* reset semaphore */
    4883                      &ulPostCounter);              /* post counter - ignored */
    4884   }
    4885 
    4886 
    4887   /* now read events into target buffer */
    4888   for (ulPostCounter = 0;
    4889        ulPostCounter < cInRecords;
    4890        ulPostCounter++,
    4891        pirBuffer++)
    4892   {
    4893     rc = ConsoleInputEventPop(pirBuffer);            /* get event from queue */
    4894     if (rc != NO_ERROR)                  /* if read error occurs, break look */
    4895       break;
    4896   }
    4897 
    4898   *lpcRead = ulPostCounter;                 /* return number of records read */
    4899   return (TRUE);                                                       /* OK */
    4900 }
    4901 
    4902 
    4903 /*****************************************************************************
    4904  * Name      : DWORD HMDeviceConsoleInClass::SetConsoleMode
    4905  * Purpose   : sets the current console mode
    4906  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    4907  *             DWORD         dwMode        - console mode
    4908  * Variables :
    4909  * Result    :
    4910  * Remark    :
    4911  * Status    : UNTESTED
    4912  *
    4913  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    4914  *****************************************************************************/
    4915 
    4916 DWORD HMDeviceConsoleInClass::SetConsoleMode(PHMHANDLEDATA pHMHandleData,
    4917                                              DWORD         dwMode)
    4918 {
    4919   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    4920 
    4921 #ifdef DEBUG_LOCAL2
    4922   WriteLog("KERNEL32/CONSOLE: CONIN$::SetConsoleMode(%08x,%08x).\n",
    4923            pHMHandleData,
    4924            dwMode);
    4925 #endif
    4926 
    4927   ConsoleInput.dwConsoleMode = dwMode;           /* set current console mode */
    4928 
    4929   return (TRUE);
    4930 }
    4931 
    4932 
    4933 /*****************************************************************************
    4934  * Name      : DWORD HMDeviceConsoleInClass::WriteConsoleInputA
    4935  * Purpose   : this writes event records directly into the queue
    4936  * Parameters: PHMHANDLEDATA pHMHandleData
    4937  *             PINPUT_RECORD pirBuffer
    4938  *             DWORD         cInRecords
    4939  *             LPDWORD       lpcWritten
    4940  * Variables :
    4941  * Result    :
    4942  * Remark    :
    4943  * Status    : NO_ERROR - API succeeded
    4944  *             other    - what is to be set in SetLastError
    4945  *
    4946  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    4947  *****************************************************************************/
    4948 
    4949 DWORD HMDeviceConsoleInClass::WriteConsoleInputA (PHMHANDLEDATA pHMHandleData,
    4950                                                   PINPUT_RECORD pirBuffer,
    4951                                                   DWORD         cInRecords,
    4952                                                   LPDWORD       lpcWritten)
    4953 {
    4954   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    4955   APIRET         rc;                                       /* API returncode */
    4956   ULONG          ulCounter;                                  /* loop counter */
    4957 
    4958 #ifdef DEBUG_LOCAL2
    4959   WriteLog("KERNEL32/CONSOLE: CONIN$::WriteConsoleInputA(%08x,%08x,%u,%08x).\n",
    4960            pHMHandleData,
    4961            pirBuffer,
    4962            cInRecords,
    4963            lpcWritten);
    4964 #endif
    4965 
    4966   for (ulCounter = 0;
    4967        ulCounter < cInRecords;
    4968        ulCounter++,
    4969        pirBuffer++)
    4970   {
    4971     rc = ConsoleInputEventPush(pirBuffer);             /* push current event */
    4972     if (rc != NO_ERROR)                     /* oops ? queue full ? problem ? */
    4973       break;
    4974   }
    4975 
    4976   *lpcWritten = ulCounter;                /* return number of events written */
    4977   return (TRUE);                                                       /* OK */
    4978 }
    4979 
    4980 
    4981 /*****************************************************************************
    4982  * Name      : DWORD HMDeviceConsoleInClass::WriteConsoleInputW
    4983  * Purpose   : this writes event records directly into the queue
    4984  * Parameters: PHMHANDLEDATA pHMHandleData
    4985  *             PINPUT_RECORD pirBuffer
    4986  *             DWORD         cInRecords
    4987  *             LPDWORD       lpcWritten
    4988  * Variables :
    4989  * Result    :
    4990  * Remark    :
    4991  * Status    : NO_ERROR - API succeeded
    4992  *             other    - what is to be set in SetLastError
    4993  *
    4994  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    4995  *****************************************************************************/
    4996 
    4997 DWORD HMDeviceConsoleInClass::WriteConsoleInputW (PHMHANDLEDATA pHMHandleData,
    4998                                                   PINPUT_RECORD pirBuffer,
    4999                                                   DWORD         cInRecords,
    5000                                                   LPDWORD       lpcWritten)
    5001 {
    5002   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    5003   APIRET         rc;                                       /* API returncode */
    5004   ULONG          ulCounter;                                  /* loop counter */
    5005 
    5006 #ifdef DEBUG_LOCAL2
    5007   WriteLog("KERNEL32/CONSOLE: CONIN$::WriteConsoleInputW(%08x,%08x,%u,%08x).\n",
    5008            pHMHandleData,
    5009            pirBuffer,
    5010            cInRecords,
    5011            lpcWritten);
    5012 #endif
    5013 
    5014   for (ulCounter = 0;
    5015        ulCounter < cInRecords;
    5016        ulCounter++,
    5017        pirBuffer++)
    5018   {
    5019     rc = ConsoleInputEventPush(pirBuffer);             /* push current event */
    5020     if (rc != NO_ERROR)                     /* oops ? queue full ? problem ? */
    5021       break;
    5022   }
    5023 
    5024   *lpcWritten = ulCounter;                /* return number of events written */
    5025   return (TRUE);                                                       /* OK */
    5026 }
    5027 
    5028 
    5029 
    5030 /*****************************************************************************
    5031  * Name      : DWORD HMDeviceConsoleOutClass::CreateFile
    5032  * Purpose   : this is called from the handle manager if a CreateFile() is
    5033  *             performed on a handle
    5034  * Parameters: LPCSTR        lpFileName            name of the file / device
    5035  *             PHMHANDLEDATA pHMHandleData         data of the NEW handle
    5036  *             PVOID         lpSecurityAttributes  ignored
    5037  *             PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
    5038  * Variables :
    5039  * Result    :
    5040  * Remark    :
    5041  * Status    : NO_ERROR - API succeeded
    5042  *             other    - what is to be set in SetLastError
    5043  *
    5044  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    5045  *****************************************************************************/
    5046 
    5047 DWORD HMDeviceConsoleOutClass::CreateFile (LPCSTR        lpFileName,
    5048                                            PHMHANDLEDATA pHMHandleData,
    5049                                            PVOID         lpSecurityAttributes,
    5050                                            PHMHANDLEDATA pHMHandleDataTemplate)
    5051 {
    5052   APIRET rc;
    5053   BOOL   fResult;
    5054   HANDLE hConsole;
    5055 
    5056 #ifdef DEBUG_LOCAL2
    5057   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass %s(%s,%08x,%08x,%08x)\n",
    5058            lpHMDeviceName,
    5059            lpFileName,
    5060            pHMHandleData->hHandle,
    5061            lpSecurityAttributes,
    5062            pHMHandleDataTemplate);
    5063 #endif
    5064 
    5065   pHMHandleData->dwType = FILE_TYPE_CHAR;        /* we're a character device */
    5066 
    5067 
    5068                  /* if no default buffer is available, then do default setup */
    5069   if (ConsoleGlobals.hConsoleBuffer == INVALID_HANDLE_VALUE)
    5070   {
    5071                 /* now we need a default screen buffer with the default size */
    5072     hConsole = CreateConsoleScreenBuffer(0,
    5073                                             0,
    5074                                             NULL,
    5075                                             CONSOLE_TEXTMODE_BUFFER,
    5076                                             NULL);
    5077     if (hConsole == INVALID_HANDLE_VALUE)
    5078     {
    5079 #ifdef DEBUG_LOCAL
    5080       WriteLog("KERNEL32/CONSOLE:OS2CreateConsoleScreenBuffer = %u.\n",
    5081                GetLastError());
    5082 #endif
    5083       return INVALID_HANDLE_VALUE;   /* abort further processing immediately */
    5084     }
    5085 
    5086     fResult = SetConsoleTextAttribute(hConsole,
    5087                                          ConsoleGlobals.Options.ucDefaultAttribute);
    5088 #ifdef DEBUG_LOCAL
    5089     if (fResult == FALSE)                                    /* check errors */
    5090       WriteLog("KERNEL32/CONSOLE:OS2SetConsoleTextAttribute=%u.\n",
    5091                GetLastError());
    5092 #endif
    5093 
    5094     fResult = SetConsoleScreenBufferSize(hConsole,
    5095                                             ConsoleGlobals.Options.coordDefaultSize);
    5096     if (fResult == FALSE)
    5097     {
    5098 #ifdef DEBUG_LOCAL
    5099       WriteLog("KERNEL32/CONSOLE:OS2SetConsoleScreenBufferSize=%u.\n",
    5100                GetLastError());
    5101 #endif
    5102       HMCloseHandle(hConsole);                          /* free handle again */
    5103       return (INVALID_HANDLE_VALUE);            /* abort further processing */
    5104     }
    5105 
    5106     fResult = SetConsoleActiveScreenBuffer(hConsole);
    5107     if (fResult == FALSE)
    5108     {
    5109 #ifdef DEBUG_LOCAL
    5110       WriteLog("KERNEL32/CONSOLE:OS2SetConsoleActiveScreenBuffer=%u.\n",
    5111                GetLastError());
    5112 #endif
    5113       HMCloseHandle(hConsole);                          /* free handle again */
    5114       return (INVALID_HANDLE_VALUE);            /* abort further processing */
    5115     }
    5116     else
    5117     {
    5118       ConsoleGlobals.hConsoleBufferDefault = hConsole;        /* save handle */
    5119       ConsoleGlobals.hConsoleBuffer        = hConsole;
    5120     }
    5121   }
    5122 
    5123   return(NO_ERROR);
    5124 }
    5125 
    5126 
    5127 /*****************************************************************************
    5128  * Name      :
    5129  * Purpose   :
    5130  * Parameters:
    5131  * Variables :
    5132  * Result    :
    5133  * Remark    :
    5134  * Status    :
    5135  *
    5136  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    5137  *****************************************************************************/
    5138 
    5139 DWORD HMDeviceConsoleOutClass::ReadFile(PHMHANDLEDATA pHMHandleData,
    5140                                         LPCVOID       lpBuffer,
    5141                                         DWORD         nNumberOfBytesToRead,
    5142                                         LPDWORD       lpNumberOfBytesRead,
    5143                                         LPOVERLAPPED  lpOverlapped)
    5144 {
    5145 
    5146 #ifdef DEBUG_LOCAL
    5147   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)\n",
    5148            lpHMDeviceName,
    5149            pHMHandleData->hHandle,
    5150            lpBuffer,
    5151            nNumberOfBytesToRead,
    5152            lpNumberOfBytesRead,
    5153            lpOverlapped);
    5154 #endif
    5155 
    5156   return(ERROR_ACCESS_DENIED);
    5157 }
    5158 
    5159 
    5160 /*****************************************************************************
    5161  * Name      :
    5162  * Purpose   :
    5163  * Parameters:
    5164  * Variables :
    5165  * Result    :
    5166  * Remark    :
    5167  * Status    :
    5168  *
    5169  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    5170  *****************************************************************************/
    5171 
    5172 DWORD HMDeviceConsoleOutClass::WriteFile(PHMHANDLEDATA pHMHandleData,
    5173                                          LPCVOID       lpBuffer,
    5174                                          DWORD         nNumberOfBytesToWrite,
    5175                                          LPDWORD       lpNumberOfBytesWritten,
    5176                                          LPOVERLAPPED  lpOverlapped)
    5177 {
    5178   DWORD dwResult;                        /* result from subsequent WriteFile */
    5179 
    5180 #ifdef DEBUG_LOCAL2
    5181   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass:WriteFile %s(%08x,%08x,%08x,%08x,%08x)\n",
    5182            lpHMDeviceName,
    5183            pHMHandleData->hHandle,
    5184            lpBuffer,
    5185            nNumberOfBytesToWrite,
    5186            lpNumberOfBytesWritten,
    5187            lpOverlapped);
    5188 #endif
    5189 
    5190         /* just prevent an endless loop, although this condition might never */
    5191                                                                 /* be true ! */
    5192   if (pHMHandleData->hHandle != ConsoleGlobals.hConsoleBuffer)
    5193   {
    5194 #if 0
    5195     HMDeviceRequest(ConsoleGlobals.hConsoleBuffer,        /* hide the cursor */
    5196                     DRQ_INTERNAL_CONSOLECURSORSHOW,
    5197                     CONSOLECURSOR_HIDE,
    5198                     0,
    5199                     0,
    5200                     0);
    5201 #endif
    5202 
    5203     dwResult = HMWriteFile(ConsoleGlobals.hConsoleBuffer,
    5204                            lpBuffer,
    5205                            nNumberOfBytesToWrite,
    5206                            lpNumberOfBytesWritten,
    5207                            lpOverlapped);
    5208 
    5209 #if 0
    5210     HMDeviceRequest(ConsoleGlobals.hConsoleBuffer,        /* show the cursor */
    5211                     DRQ_INTERNAL_CONSOLECURSORSHOW,
    5212                     CONSOLECURSOR_SHOW,
    5213                     0,
    5214                     0,
    5215                     0);
    5216 #endif
    5217 
    5218     return (dwResult);                                 /* return result code */
    5219   }
    5220   else
    5221     return (ERROR_SYS_INTERNAL);                    /* raise error condition */
    5222 }
    5223 
    5224 
    5225 /*****************************************************************************
    5226  * Name      : DWORD HMDeviceConsoleOutClass::_DeviceRequest
    5227  * Purpose   : we just forward those device requests to the console buffer
    5228  *             currently associated with the console itself.
    5229  * Parameters:
    5230  * Variables :
    5231  * Result    :
    5232  * Remark    :
    5233  * Status    : UNTESTED
    5234  *
    5235  * Author    : Patrick Haller [Wed, 1998/03/35 20:44]
    5236  *****************************************************************************/
    5237 
    5238 DWORD HMDeviceConsoleOutClass::_DeviceRequest (PHMHANDLEDATA pHMHandleData,
    5239                                                ULONG         ulRequestCode,
    5240                                                ULONG         arg1,
    5241                                                ULONG         arg2,
    5242                                                ULONG         arg3,
    5243                                                ULONG         arg4)
    5244 {
    5245 #ifdef DEBUG_LOCAL2
    5246   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleOutClass:_DeviceRequest %s(%08x,%08x,%08x,%08x,%08x,%08x)\n",
    5247            lpHMDeviceName,
    5248            pHMHandleData->hHandle,
    5249            ulRequestCode,
    5250            arg1,
    5251            arg2,
    5252            arg3,
    5253            arg4);
    5254 #endif
    5255         /* just prevent an endless loop, although this condition might never */
    5256                                                                 /* be true ! */
    5257   if (pHMHandleData->hHandle != ConsoleGlobals.hConsoleBuffer)
    5258     return (HMDeviceRequest(ConsoleGlobals.hConsoleBuffer,
    5259                             ulRequestCode,
    5260                             arg1,
    5261                             arg2,
    5262                             arg3,
    5263                             arg4));
    5264   else
    5265     return (ERROR_SYS_INTERNAL);                    /* raise error condition */
    5266 }
    5267 
    5268 
    5269 /*****************************************************************************
    5270  * Name      : DWORD HMDeviceConsoleBufferClass::CreateFile
    5271  * Purpose   : this is called from the handle manager if a CreateFile() is
    5272  *             performed on a handle
    5273  * Parameters: LPCSTR        lpFileName            name of the file / device
    5274  *             PHMHANDLEDATA pHMHandleData         data of the NEW handle
    5275  *             PVOID         lpSecurityAttributes  ignored
    5276  *             PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
    5277  * Variables :
    5278  * Result    :
    5279  * Remark    :
    5280  * Status    : NO_ERROR - API succeeded
    5281  *             other    - what is to be set in SetLastError
    5282  *
    5283  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    5284  *****************************************************************************/
    5285 
    5286 DWORD HMDeviceConsoleBufferClass::CreateFile (LPCSTR        lpFileName,
    5287                                               PHMHANDLEDATA pHMHandleData,
    5288                                               PVOID         lpSecurityAttributes,
    5289                                               PHMHANDLEDATA pHMHandleDataTemplate)
    5290 {
    5291   PCONSOLEBUFFER pConsoleBuffer;                 /* console buffer structure */
    5292 
    5293 #ifdef DEBUG_LOCAL
    5294   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass %s(%s,%08x,%08x,%08x)\n",
    5295            lpHMDeviceName,
    5296            lpFileName,
    5297            pHMHandleData->hHandle,
    5298            lpSecurityAttributes,
    5299            pHMHandleDataTemplate);
    5300 #endif
    5301 
    5302   pHMHandleData->dwType = FILE_TYPE_CHAR;        /* we're a character device */
    5303 
    5304   pHMHandleData->lpHandlerData = malloc ( sizeof(CONSOLEBUFFER) );
    5305 
    5306 #ifdef DEBUG_LOCAL
    5307   WriteLog("KERNEL32/CONSOLE:CheckPoint1: %s pHMHandleData=%08xh, lpHandlerData=%08xh\n",
    5308            lpFileName,
    5309            pHMHandleData,
    5310            pHMHandleData->lpHandlerData);
    5311 #endif
    5312 
    5313 
    5314   if (pHMHandleData->lpHandlerData == NULL)              /* check allocation */
    5315   {
    5316     SetLastError(ERROR_NOT_ENOUGH_MEMORY);          /* set error information */
    5317     return (INVALID_HANDLE_VALUE);                  /* raise error condition */
    5318   }
    5319   else
    5320   {
    5321     pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    5322 
    5323     memset(pHMHandleData->lpHandlerData,             /* initialize structure */
    5324            0,
    5325            sizeof (CONSOLEBUFFER) );
    5326 
    5327                                                       /* set buffer defaults */
    5328     pConsoleBuffer->dwConsoleMode = ENABLE_PROCESSED_OUTPUT |
    5329                                     ENABLE_WRAP_AT_EOL_OUTPUT;
    5330 
    5331     pConsoleBuffer->CursorInfo.dwSize   = 2;                  /* 2 scanlines */
    5332     pConsoleBuffer->CursorInfo.bVisible = TRUE;
    5333   }
    5334 
    5335   return(NO_ERROR);
    5336 }
    5337 
    5338 
    5339 /*****************************************************************************
    5340  * Name      :
    5341  * Purpose   :
    5342  * Parameters:
    5343  * Variables :
    5344  * Result    :
    5345  * Remark    :
    5346  * Status    :
    5347  *
    5348  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    5349  *****************************************************************************/
    5350 
    5351 DWORD HMDeviceConsoleBufferClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
    5352 {
    5353 
    5354 #ifdef DEBUG_LOCAL
    5355   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass::CloseHandle %s(%08x)\n",
    5356            lpHMDeviceName,
    5357            pHMHandleData);
    5358 #endif
    5359 
    5360   if (pHMHandleData->lpHandlerData != NULL)                 /* check pointer */
    5361   {
    5362     PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    5363 
    5364 
    5365     if (pConsoleBuffer->ppszLine != NULL)        /* free line buffer array ! */
    5366       free (pConsoleBuffer->ppszLine);
    5367 
    5368     free (pHMHandleData->lpHandlerData);          /* free device object data */
    5369     pHMHandleData->lpHandlerData = NULL;
    5370   }
    5371 
    5372   return(NO_ERROR);
    5373 }
    5374 
    5375 
    5376 /*****************************************************************************
    5377  * Name      :
    5378  * Purpose   :
    5379  * Parameters:
    5380  * Variables :
    5381  * Result    :
    5382  * Remark    :
    5383  * Status    :
    5384  *
    5385  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    5386  *****************************************************************************/
    5387 
    5388 DWORD HMDeviceConsoleBufferClass::ReadFile(PHMHANDLEDATA pHMHandleData,
    5389                                            LPCVOID       lpBuffer,
    5390                                            DWORD         nNumberOfBytesToRead,
    5391                                            LPDWORD       lpNumberOfBytesRead,
    5392                                            LPOVERLAPPED  lpOverlapped)
    5393 {
    5394 
    5395 #ifdef DEBUG_LOCAL
    5396   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)\n",
    5397            lpHMDeviceName,
    5398            pHMHandleData->hHandle,
    5399            lpBuffer,
    5400            nNumberOfBytesToRead,
    5401            lpNumberOfBytesRead,
    5402            lpOverlapped);
    5403 #endif
    5404 
    5405   return(ERROR_ACCESS_DENIED);
    5406 }
    5407 
    5408 
    5409 /*****************************************************************************
    5410  * Name      :
    5411  * Purpose   :
    5412  * Parameters:
    5413  * Variables :
    5414  * Result    :
    5415  * Remark    :
    5416  * Status    :
    5417  *
    5418  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    5419  *****************************************************************************/
    5420 
    5421 DWORD HMDeviceConsoleBufferClass::WriteFile(PHMHANDLEDATA pHMHandleData,
    5422                                             LPCVOID       lpBuffer,
    5423                                             DWORD         nNumberOfBytesToWrite,
    5424                                             LPDWORD       lpNumberOfBytesWritten,
    5425                                             LPOVERLAPPED  lpOverlapped)
    5426 {
    5427   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    5428            ULONG ulCounter;                 /* counter for the byte transfer */
    5429            PSZ   pszBuffer = (PSZ)lpBuffer;
    5430   register UCHAR ucChar;
    5431 
    5432 #ifdef DEBUG_LOCAL2
    5433   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass:WriteFile %s(%08x,%08x,%08x,%08x,%08x)\n",
    5434            lpHMDeviceName,
    5435            pHMHandleData->hHandle,
    5436            lpBuffer,
    5437            nNumberOfBytesToWrite,
    5438            lpNumberOfBytesWritten,
    5439            lpOverlapped);
    5440 #endif
    5441 
    5442                       /* check if we're called with non-existing line buffer */
    5443   if (pConsoleBuffer->ppszLine == NULL)
    5444     return (ERROR_SYS_INTERNAL);
    5445 
    5446   for (ulCounter = 0;
    5447        ulCounter < nNumberOfBytesToWrite;
    5448        ulCounter++)
    5449   {
    5450     ucChar = pszBuffer[ulCounter];                        /* map to register */
    5451 
    5452     if ( (pConsoleBuffer->dwConsoleMode & ENABLE_PROCESSED_OUTPUT) &&
    5453          (ucChar < 32) )     /* this is faster than a large switch statement */
    5454     {
    5455       switch (ucChar)
    5456       {
    5457         case 7: /* BEL */
    5458           if (ConsoleGlobals.Options.fSpeakerEnabled == TRUE)
    5459             DosBeep(ConsoleGlobals.Options.ulSpeakerFrequency,
    5460                     ConsoleGlobals.Options.ulSpeakerDuration);
    5461           break;
    5462 
    5463         case 8: /* Backspace */
    5464           if (pConsoleBuffer->coordCursorPosition.X > 0)
    5465             pConsoleBuffer->coordCursorPosition.X--;
    5466           break;
    5467 
    5468         case 9: /* Tab */
    5469           pConsoleBuffer->coordCursorPosition.X =
    5470             (pConsoleBuffer->coordCursorPosition.X
    5471              / ConsoleGlobals.Options.ulTabSize
    5472              + 1)
    5473             * ConsoleGlobals.Options.ulTabSize;
    5474 
    5475           if (pConsoleBuffer->coordCursorPosition.X >=
    5476               pConsoleBuffer->coordBufferSize.X)
    5477           {
    5478             pConsoleBuffer->coordCursorPosition.X = 0;
    5479             pConsoleBuffer->coordCursorPosition.Y++;
    5480 
    5481             if (pConsoleBuffer->coordCursorPosition.Y >=
    5482                 pConsoleBuffer->coordBufferSize.Y)
    5483             {
    5484               if (pConsoleBuffer->dwConsoleMode & ENABLE_WRAP_AT_EOL_OUTPUT)
    5485               {
    5486                 ConsoleBufferScrollUp(pConsoleBuffer,    /* scroll one line up */
    5487                                       1);
    5488                 pConsoleBuffer->coordCursorPosition.Y--;
    5489               }
    5490             }
    5491           }
    5492           break;
    5493 
    5494         case 10: /* LINEFEED */
    5495           pConsoleBuffer->coordCursorPosition.Y++;
    5496 
    5497           if (pConsoleBuffer->coordCursorPosition.Y >=
    5498               pConsoleBuffer->coordBufferSize.Y)
    5499           {
    5500             ConsoleBufferScrollUp(pConsoleBuffer,      /* scroll one line up */
    5501                                   1);
    5502             pConsoleBuffer->coordCursorPosition.Y--;
    5503           }
    5504           break;
    5505 
    5506         case 13: /* CARRIAGE RETURN */
    5507           pConsoleBuffer->coordCursorPosition.X = 0;
    5508           break;
    5509 
    5510         default:
    5511           break;
    5512       }
    5513     }
    5514     else
    5515     {
    5516                                                           /* write character */
    5517       *(pConsoleBuffer->ppszLine[pConsoleBuffer->coordCursorPosition.Y] +
    5518         pConsoleBuffer->coordCursorPosition.X * 2) = pszBuffer[ulCounter];
    5519 
    5520       pConsoleBuffer->coordCursorPosition.X++;
    5521 
    5522       if (pConsoleBuffer->coordCursorPosition.X >=
    5523           pConsoleBuffer->coordBufferSize.X)
    5524       {
    5525         pConsoleBuffer->coordCursorPosition.X = 0;
    5526         pConsoleBuffer->coordCursorPosition.Y++;
    5527 
    5528         if (pConsoleBuffer->coordCursorPosition.Y >=
    5529             pConsoleBuffer->coordBufferSize.Y)
    5530         {
    5531           if (pConsoleBuffer->dwConsoleMode & ENABLE_WRAP_AT_EOL_OUTPUT)
    5532           {
    5533             ConsoleBufferScrollUp(pConsoleBuffer,      /* scroll one line up */
    5534                                   1);
    5535             pConsoleBuffer->coordCursorPosition.Y--;
    5536           }
    5537           else
    5538           {
    5539                                               /* just stay on last character */
    5540             pConsoleBuffer->coordCursorPosition.X = pConsoleBuffer->coordBufferSize.X - 1;
    5541             pConsoleBuffer->coordCursorPosition.Y = pConsoleBuffer->coordBufferSize.Y - 1;
    5542           }
    5543         }
    5544       }
    5545     }
    5546   }
    5547 
    5548                                           /* update screen if active console */
    5549   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    5550     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    5551 
    5552   *lpNumberOfBytesWritten = ulCounter;
    5553 
    5554   return(ulCounter);
    5555 }
    5556 
    5557 
    5558 /*****************************************************************************
    5559  * Name      :
    5560  * Purpose   :
    5561  * Parameters:
    5562  * Variables :
    5563  * Result    :
    5564  * Remark    :
    5565  * Status    :
    5566  *
    5567  * Author    : Patrick Haller [Wed, 1998/02/11 20:44]
    5568  *****************************************************************************/
    5569 
    5570 DWORD  HMDeviceConsoleBufferClass::_DeviceRequest (PHMHANDLEDATA pHMHandleData,
    5571                                                    ULONG         ulRequestCode,
    5572                                                    ULONG         arg1,
    5573                                                    ULONG         arg2,
    5574                                                    ULONG         arg3,
    5575                                                    ULONG         arg4)
    5576 {
    5577   switch (ulRequestCode)
    5578   {
    5579     case DRQ_FILLCONSOLEOUTPUTATTRIBUTE:
    5580     {
    5581       COORD coordWrite;
    5582 
    5583       ULONG2COORD(coordWrite,arg3);
    5584 
    5585       return (HMDeviceConsoleBufferClass
    5586               ::FillConsoleOutputAttribute(pHMHandleData,
    5587                                            (WORD)arg1,
    5588                                            (DWORD)arg2,
    5589                                            coordWrite,
    5590                                            (LPDWORD)arg4));
    5591     }
    5592 
    5593 
    5594     case DRQ_FILLCONSOLEOUTPUTCHARACTERA:
    5595     {
    5596       COORD coordWrite;
    5597 
    5598       ULONG2COORD(coordWrite,arg3);
    5599 
    5600       return (HMDeviceConsoleBufferClass
    5601               ::FillConsoleOutputCharacterA(pHMHandleData,
    5602                                             (UCHAR)arg1,
    5603                                             (DWORD)arg2,
    5604                                             coordWrite,
    5605                                             (LPDWORD)arg4));
    5606     }
    5607 
    5608 
    5609     case DRQ_FILLCONSOLEOUTPUTCHARACTERW:
    5610     {
    5611       COORD coordWrite;
    5612 
    5613       ULONG2COORD(coordWrite,arg3);
    5614 
    5615       return (HMDeviceConsoleBufferClass
    5616               ::FillConsoleOutputCharacterW(pHMHandleData,
    5617                                             (WCHAR)arg1,
    5618                                             (DWORD)arg2,
    5619                                             coordWrite,
    5620                                             (LPDWORD)arg4));
    5621     }
    5622 
    5623 
    5624     case DRQ_GETCONSOLECURSORINFO:
    5625       return (HMDeviceConsoleBufferClass
    5626               ::GetConsoleCursorInfo(pHMHandleData,
    5627                                      (PCONSOLE_CURSOR_INFO)arg1));
    5628 
    5629 
    5630     case DRQ_GETCONSOLEMODE:
    5631       return (HMDeviceConsoleBufferClass
    5632               ::GetConsoleMode(pHMHandleData,
    5633                                (LPDWORD)arg1));
    5634 
    5635 
    5636     case DRQ_GETCONSOLESCREENBUFFERINFO:
    5637       return (HMDeviceConsoleBufferClass
    5638               ::GetConsoleScreenBufferInfo(pHMHandleData,
    5639                                            (PCONSOLE_SCREEN_BUFFER_INFO)arg1));
    5640 
    5641 
    5642     case DRQ_GETLARGESTCONSOLEWINDOWSIZE:
    5643       return (HMDeviceConsoleBufferClass
    5644               ::GetLargestConsoleWindowSize(pHMHandleData));
    5645 
    5646 
    5647     case DRQ_READCONSOLEOUTPUTA:
    5648     {
    5649       COORD coordDestBufferSize;
    5650       COORD coordDestBufferCoord;
    5651 
    5652       ULONG2COORD(coordDestBufferSize,  arg2);
    5653       ULONG2COORD(coordDestBufferCoord, arg3);
    5654 
    5655       return (HMDeviceConsoleBufferClass
    5656               ::ReadConsoleOutputA(pHMHandleData,
    5657                                    (PCHAR_INFO)arg1,
    5658                                    coordDestBufferSize,
    5659                                    coordDestBufferCoord,
    5660                                    (PSMALL_RECT)arg4));
    5661     }
    5662 
    5663 
    5664     case DRQ_READCONSOLEOUTPUTW:
    5665     {
    5666       COORD coordDestBufferSize;
    5667       COORD coordDestBufferCoord;
    5668 
    5669       ULONG2COORD(coordDestBufferSize,  arg2);
    5670       ULONG2COORD(coordDestBufferCoord, arg3);
    5671 
    5672       return (HMDeviceConsoleBufferClass
    5673               ::ReadConsoleOutputW(pHMHandleData,
    5674                                    (PCHAR_INFO)arg1,
    5675                                    coordDestBufferSize,
    5676                                    coordDestBufferCoord,
    5677                                    (PSMALL_RECT)arg4));
    5678     }
    5679 
    5680 
    5681     case DRQ_READCONSOLEOUTPUTATTRIBUTE:
    5682     {
    5683       COORD coordReadCoord;
    5684 
    5685       ULONG2COORD(coordReadCoord, arg3);
    5686 
    5687       return (HMDeviceConsoleBufferClass
    5688               ::ReadConsoleOutputAttribute(pHMHandleData,
    5689                                    (LPWORD)arg1,
    5690                                    (DWORD)arg2,
    5691                                    coordReadCoord,
    5692                                    (LPDWORD)arg4));
    5693     }
    5694 
    5695 
    5696     case DRQ_READCONSOLEOUTPUTCHARACTERA:
    5697     {
    5698       COORD coordReadCoord;
    5699 
    5700       ULONG2COORD(coordReadCoord, arg3);
    5701 
    5702       return (HMDeviceConsoleBufferClass
    5703               ::ReadConsoleOutputCharacterA(pHMHandleData,
    5704                                             (LPTSTR)arg1,
    5705                                             (DWORD)arg2,
    5706                                             coordReadCoord,
    5707                                             (LPDWORD)arg4));
    5708     }
    5709 
    5710 
    5711     case DRQ_READCONSOLEOUTPUTCHARACTERW:
    5712     {
    5713       COORD coordReadCoord;
    5714 
    5715       ULONG2COORD(coordReadCoord, arg3);
    5716 
    5717       return (HMDeviceConsoleBufferClass
    5718               ::ReadConsoleOutputCharacterW(pHMHandleData,
    5719                                             (LPWSTR)arg1,
    5720                                             (DWORD)arg2,
    5721                                             coordReadCoord,
    5722                                             (LPDWORD)arg4));
    5723     }
    5724 
    5725 
    5726     case DRQ_SCROLLCONSOLESCREENBUFFERA:
    5727     {
    5728       COORD coordDestOrigin;
    5729 
    5730       ULONG2COORD(coordDestOrigin, arg3);
    5731 
    5732       return (HMDeviceConsoleBufferClass
    5733               ::ScrollConsoleScreenBufferA(pHMHandleData,
    5734                                            (PSMALL_RECT)arg1,
    5735                                            (PSMALL_RECT)arg2,
    5736                                            coordDestOrigin,
    5737                                            (PCHAR_INFO)arg4));
    5738     }
    5739 
    5740 
    5741     case DRQ_SCROLLCONSOLESCREENBUFFERW:
    5742     {
    5743       COORD coordDestOrigin;
    5744 
    5745       ULONG2COORD(coordDestOrigin, arg3);
    5746 
    5747       return (HMDeviceConsoleBufferClass
    5748               ::ScrollConsoleScreenBufferW(pHMHandleData,
    5749                                            (PSMALL_RECT)arg1,
    5750                                            (PSMALL_RECT)arg2,
    5751                                            coordDestOrigin,
    5752                                            (PCHAR_INFO)arg4));
    5753     }
    5754 
    5755 
    5756     case DRQ_SETCONSOLEACTIVESCREENBUFFER:
    5757       return (HMDeviceConsoleBufferClass
    5758               ::SetConsoleActiveScreenBuffer(pHMHandleData));
    5759 
    5760 
    5761     case DRQ_SETCONSOLECURSORINFO:
    5762       return (HMDeviceConsoleBufferClass
    5763               ::SetConsoleCursorInfo(pHMHandleData,
    5764                                      (PCONSOLE_CURSOR_INFO)arg1));
    5765 
    5766 
    5767     case DRQ_SETCONSOLECURSORPOSITION:
    5768     {
    5769       COORD coordCursor;
    5770 
    5771       ULONG2COORD(coordCursor, arg1);
    5772 
    5773       return (HMDeviceConsoleBufferClass
    5774               ::SetConsoleCursorPosition(pHMHandleData,
    5775                                          coordCursor));
    5776     }
    5777 
    5778 
    5779     case DRQ_SETCONSOLEMODE:
    5780       return (HMDeviceConsoleBufferClass
    5781               ::SetConsoleMode(pHMHandleData,
    5782                                (DWORD)arg1));
    5783 
    5784 
    5785     case DRQ_SETCONSOLESCREENBUFFERSIZE:
    5786     {
    5787       COORD coordSize;
    5788 
    5789       ULONG2COORD(coordSize,arg1);
    5790 
    5791       return (HMDeviceConsoleBufferClass::
    5792                 SetConsoleScreenBufferSize(pHMHandleData,
    5793                                            coordSize));
    5794     }
    5795 
    5796 
    5797     case DRQ_SETCONSOLETEXTATTRIBUTE:
    5798       return (HMDeviceConsoleBufferClass::
    5799                 SetConsoleTextAttribute(pHMHandleData,
    5800                                         (WORD)arg1));
    5801 
    5802 
    5803     case DRQ_SETCONSOLEWINDOWINFO:
    5804       return (HMDeviceConsoleBufferClass
    5805               ::SetConsoleWindowInfo(pHMHandleData,
    5806                                      (BOOL)arg1,
    5807                                      (PSMALL_RECT)arg2));
    5808 
    5809 
    5810     case DRQ_WRITECONSOLEA:
    5811       return (HMDeviceConsoleBufferClass
    5812               ::WriteConsoleA(pHMHandleData,
    5813                               (CONST VOID*)arg1,
    5814                               (DWORD)arg2,
    5815                               (LPDWORD)arg3,
    5816                               (LPVOID)arg4));
    5817 
    5818 
    5819     case DRQ_WRITECONSOLEW:
    5820       return (HMDeviceConsoleBufferClass
    5821               ::WriteConsoleW(pHMHandleData,
    5822                               (CONST VOID*)arg1,
    5823                               (DWORD)arg2,
    5824                               (LPDWORD)arg3,
    5825                               (LPVOID)arg4));
    5826 
    5827 
    5828     case DRQ_WRITECONSOLEOUTPUTA:
    5829     {
    5830       COORD coordSrcBufferSize;
    5831       COORD coordSrcBufferCoord;
    5832 
    5833       ULONG2COORD(coordSrcBufferSize,  arg2);
    5834       ULONG2COORD(coordSrcBufferCoord, arg3);
    5835 
    5836       return (HMDeviceConsoleBufferClass
    5837               ::WriteConsoleOutputA(pHMHandleData,
    5838                                     (PCHAR_INFO)arg1,
    5839                                     coordSrcBufferSize,
    5840                                     coordSrcBufferCoord,
    5841                                     (PSMALL_RECT)arg4));
    5842     }
    5843 
    5844 
    5845     case DRQ_WRITECONSOLEOUTPUTW:
    5846     {
    5847       COORD coordSrcBufferSize;
    5848       COORD coordSrcBufferCoord;
    5849 
    5850       ULONG2COORD(coordSrcBufferSize,  arg2);
    5851       ULONG2COORD(coordSrcBufferCoord, arg3);
    5852 
    5853       return (HMDeviceConsoleBufferClass
    5854               ::WriteConsoleOutputA(pHMHandleData,
    5855                                     (PCHAR_INFO)arg1,
    5856                                     coordSrcBufferSize,
    5857                                     coordSrcBufferCoord,
    5858                                     (PSMALL_RECT)arg4));
    5859     }
    5860 
    5861 
    5862     case DRQ_WRITECONSOLEOUTPUTATTRIBUTE:
    5863     {
    5864       COORD coordWriteCoord;
    5865 
    5866       ULONG2COORD(coordWriteCoord,  arg3);
    5867 
    5868       return (HMDeviceConsoleBufferClass
    5869               ::WriteConsoleOutputAttribute(pHMHandleData,
    5870                                             (LPWORD)arg1,
    5871                                             (DWORD)arg2,
    5872                                             coordWriteCoord,
    5873                                             (LPDWORD)arg4));
    5874     }
    5875 
    5876 
    5877     case DRQ_WRITECONSOLEOUTPUTCHARACTERA:
    5878     {
    5879       COORD coordWriteCoord;
    5880 
    5881       ULONG2COORD(coordWriteCoord,  arg3);
    5882 
    5883       return (HMDeviceConsoleBufferClass
    5884               ::WriteConsoleOutputCharacterA(pHMHandleData,
    5885                                              (LPTSTR)arg1,
    5886                                              (DWORD)arg2,
    5887                                              coordWriteCoord,
    5888                                              (LPDWORD)arg4));
    5889     }
    5890 
    5891 
    5892     case DRQ_WRITECONSOLEOUTPUTCHARACTERW:
    5893     {
    5894       COORD coordWriteCoord;
    5895 
    5896       ULONG2COORD(coordWriteCoord,  arg3);
    5897 
    5898       return (HMDeviceConsoleBufferClass
    5899               ::WriteConsoleOutputCharacterW(pHMHandleData,
    5900                                              (LPWSTR)arg1,
    5901                                              (DWORD)arg2,
    5902                                              coordWriteCoord,
    5903                                              (LPDWORD)arg4));
    5904     }
    5905 
    5906 
    5907     case DRQ_INTERNAL_CONSOLEBUFFERMAP:
    5908       ConsoleBufferMap((PCONSOLEBUFFER)pHMHandleData->lpHandlerData);
    5909       return (NO_ERROR);
    5910 
    5911 
    5912     case DRQ_INTERNAL_CONSOLECURSORSHOW:
    5913       ConsoleCursorShow((PCONSOLEBUFFER)pHMHandleData->lpHandlerData,
    5914                         (ULONG)arg1);
    5915       return (NO_ERROR);
    5916 
    5917 
    5918     case DRQ_INTERNAL_CONSOLEADJUSTWINDOW:
    5919       ConsoleAdjustWindow((PCONSOLEBUFFER)pHMHandleData->lpHandlerData);
    5920       return (NO_ERROR);
    5921   }
    5922 
    5923 
    5924 #ifdef DEBUG_LOCAL
    5925   WriteLog("KERNEL32/CONSOLE:HMDeviceConsoleBufferClass:_DeviceRequest %s(%08x,%08x,%08x,%08x,%08x,%08x) unknown request\n",
    5926            lpHMDeviceName,
    5927            pHMHandleData->hHandle,
    5928            ulRequestCode,
    5929            arg1,
    5930            arg2,
    5931            arg3,
    5932            arg4);
    5933 #endif
    5934 
    5935   SetLastError(ERROR_INVALID_FUNCTION);           /* request not implemented */
    5936   return(FALSE);                 /* we assume this indicates API call failed */
    5937 }
    5938 
    5939 
    5940 /*****************************************************************************
    5941  * Name      : DWORD HMDeviceConsoleBufferClass::FillConsoleOutputAttribute
    5942  * Purpose   : fills the console buffer with a specified attribute
    5943  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    5944  *             WORD          wAttribute
    5945  *             DWORD         nLength
    5946  *             COORD         dwWriteCoord
    5947  *             LPDWORD       lpNumberOfAttrsWritten
    5948  * Variables :
    5949  * Result    :
    5950  * Remark    :
    5951  * Status    : UNTESTED
    5952  *
    5953  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    5954  *****************************************************************************/
    5955 
    5956 DWORD HMDeviceConsoleBufferClass::FillConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,
    5957                                                              WORD    wAttribute,
    5958                                                              DWORD   nLength,
    5959                                                              COORD   dwWriteCoord,
    5960                                                              LPDWORD lpNumberOfAttrsWritten)
    5961 {
    5962   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    5963   ULONG          ulCounter;                     /* current character counter */
    5964 
    5965 #ifdef DEBUG_LOCAL2
    5966   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::FillConsoleOutputAttribute(%08x,attr=%04x,%u,x=%u y=%u,res=%08x).\n",
    5967            pHMHandleData,
    5968            wAttribute,
    5969            nLength,
    5970            dwWriteCoord.X,
    5971            dwWriteCoord.Y,
    5972            lpNumberOfAttrsWritten);
    5973 #endif
    5974 
    5975   if ( (dwWriteCoord.X < 0) ||
    5976        (dwWriteCoord.Y < 0) )
    5977   {
    5978     if (lpNumberOfAttrsWritten != NULL)           /* ensure pointer is valid */
    5979       *lpNumberOfAttrsWritten = 0;                /* complete error handling */
    5980 
    5981     SetLastError(ERROR_INVALID_PARAMETER);
    5982     return (FALSE);
    5983   }
    5984 
    5985                                     /* check if dwWriteCoord is within specs */
    5986   if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
    5987        (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
    5988   {
    5989     if (lpNumberOfAttrsWritten != NULL)           /* ensure pointer is valid */
    5990       *lpNumberOfAttrsWritten = 0;                /* complete error handling */
    5991 
    5992     SetLastError(ERROR_INVALID_PARAMETER);
    5993     return (FALSE);
    5994   }
    5995 
    5996 
    5997                                         /* OK, now write the attribute lines */
    5998   for (ulCounter = 0;
    5999        ulCounter < nLength;
    6000        ulCounter++)
    6001   {
    6002                                                 /* write attribute into cell */
    6003     *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
    6004                               (dwWriteCoord.X * 2 + 1)
    6005      ) = (UCHAR)(wAttribute & 0xFF);
    6006                                  /* write attribute, don't change characters */
    6007 
    6008     dwWriteCoord.X++;                                 /* move write position */
    6009     if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
    6010     {
    6011       dwWriteCoord.X = 0;                               /* skip to next line */
    6012       dwWriteCoord.Y++;
    6013 
    6014                          /* oops, we're at the end of the buffer. Abort now. */
    6015       if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
    6016       {
    6017         if (lpNumberOfAttrsWritten != NULL)       /* ensure pointer is valid */
    6018           *lpNumberOfAttrsWritten = ulCounter;
    6019 
    6020                                           /* update screen if active console */
    6021         if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    6022           ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */
    6023 
    6024         return (TRUE);
    6025       }
    6026     }
    6027   }
    6028 
    6029                                           /* update screen if active console */
    6030   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    6031     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    6032 
    6033   if (lpNumberOfAttrsWritten != NULL)             /* ensure pointer is valid */
    6034     *lpNumberOfAttrsWritten = nLength;
    6035 
    6036   return (TRUE);
    6037 }
    6038 
    6039 
    6040 /*****************************************************************************
    6041  * Name      : DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterA
    6042  * Purpose   : fills the console buffer with a specified ASCII character
    6043  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6044  *             UCHAR         ucCharacter
    6045  *             DWORD         nLength
    6046  *             COORD         dwWriteCoord
    6047  *             LPDWORD       lpNumberOfCharsWritten
    6048  * Variables :
    6049  * Result    :
    6050  * Remark    :
    6051  * Status    : UNTESTED
    6052  *
    6053  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6054  *****************************************************************************/
    6055 
    6056 DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,
    6057                                                               UCHAR   ucCharacter,
    6058                                                               DWORD   nLength,
    6059                                                               COORD   dwWriteCoord,
    6060                                                               LPDWORD lpNumberOfCharsWritten)
    6061 {
    6062   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6063   ULONG          ulCounter;                     /* current character counter */
    6064 
    6065 #ifdef DEBUG_LOCAL2
    6066   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::FillConsoleOutputCharacterA(%08x,char=%02x,%u,x=%u y=%u,res=%08x).\n",
    6067            pHMHandleData,
    6068            ucCharacter,
    6069            nLength,
    6070            dwWriteCoord.X,
    6071            dwWriteCoord.Y,
    6072            lpNumberOfCharsWritten);
    6073 #endif
    6074 
    6075   if ( (dwWriteCoord.X < 0) ||
    6076        (dwWriteCoord.Y < 0) )
    6077   {
    6078     if (lpNumberOfCharsWritten != NULL)           /* ensure pointer is valid */
    6079       *lpNumberOfCharsWritten = 0;                /* complete error handling */
    6080 
    6081     SetLastError(ERROR_INVALID_PARAMETER);
    6082     return (FALSE);
    6083   }
    6084 
    6085 
    6086                                     /* check if dwWriteCoord is within specs */
    6087   if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
    6088        (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
    6089   {
    6090     if (lpNumberOfCharsWritten != NULL)           /* ensure pointer is valid */
    6091       *lpNumberOfCharsWritten = 0;                /* complete error handling */
    6092 
    6093     SetLastError(ERROR_INVALID_PARAMETER);
    6094     return (FALSE);
    6095   }
    6096 
    6097 
    6098                                         /* OK, now write the attribute lines */
    6099   for (ulCounter = 0;
    6100        ulCounter < nLength;
    6101        ulCounter++)
    6102   {
    6103                                                 /* write character into cell */
    6104     *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
    6105                               (dwWriteCoord.X * 2)
    6106      ) = ucCharacter;
    6107 
    6108     dwWriteCoord.X++;                                 /* move write position */
    6109     if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
    6110     {
    6111       dwWriteCoord.X = 0;                               /* skip to next line */
    6112       dwWriteCoord.Y++;
    6113 
    6114                          /* oops, we're at the end of the buffer. Abort now. */
    6115       if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
    6116       {
    6117         if (lpNumberOfCharsWritten != NULL)       /* ensure pointer is valid */
    6118           *lpNumberOfCharsWritten = ulCounter;
    6119 
    6120                                           /* update screen if active console */
    6121         if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    6122           ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */
    6123 
    6124         return (TRUE);
    6125       }
    6126     }
    6127   }
    6128 
    6129                                           /* update screen if active console */
    6130   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    6131     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    6132 
    6133   if (lpNumberOfCharsWritten != NULL)             /* ensure pointer is valid */
    6134     *lpNumberOfCharsWritten = nLength;
    6135 
    6136   return (TRUE);
    6137 }
    6138 
    6139 
    6140 /*****************************************************************************
    6141  * Name      : DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterW
    6142  * Purpose   : fills the console buffer with a specified ASCII character
    6143  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6144  *             WCHAR         wcCharacter
    6145  *             DWORD         nLength
    6146  *             COORD         dwWriteCoord
    6147  *             LPDWORD       lpNumberOfCharsWritten
    6148  * Variables :
    6149  * Result    :
    6150  * Remark    :
    6151  * Status    : UNTESTED
    6152  *
    6153  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6154  *****************************************************************************/
    6155 
    6156 DWORD HMDeviceConsoleBufferClass::FillConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,
    6157                                                               WCHAR   wcCharacter,
    6158                                                               DWORD   nLength,
    6159                                                               COORD   dwWriteCoord,
    6160                                                               LPDWORD lpNumberOfCharsWritten)
    6161 {
    6162   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6163   ULONG          ulCounter;                     /* current character counter */
    6164 
    6165 #ifdef DEBUG_LOCAL2
    6166   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::FillConsoleOutputCharacterW(%08x,char=%02x,%u,x=%u y=%u,res=%08x).\n",
    6167            pHMHandleData,
    6168            wcCharacter,
    6169            nLength,
    6170            dwWriteCoord.X,
    6171            dwWriteCoord.Y,
    6172            lpNumberOfCharsWritten);
    6173 #endif
    6174 
    6175   if ( (dwWriteCoord.X < 0) ||
    6176        (dwWriteCoord.Y < 0) )
    6177   {
    6178     if (lpNumberOfCharsWritten != NULL)           /* ensure pointer is valid */
    6179       *lpNumberOfCharsWritten = 0;                /* complete error handling */
    6180 
    6181     SetLastError(ERROR_INVALID_PARAMETER);
    6182     return (FALSE);
    6183   }
    6184 
    6185 
    6186                                     /* check if dwWriteCoord is within specs */
    6187   if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
    6188        (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
    6189   {
    6190     if (lpNumberOfCharsWritten != NULL)           /* ensure pointer is valid */
    6191       *lpNumberOfCharsWritten = 0;                /* complete error handling */
    6192 
    6193     SetLastError(ERROR_INVALID_PARAMETER);
    6194     return (FALSE);
    6195   }
    6196 
    6197 
    6198                                         /* OK, now write the attribute lines */
    6199   for (ulCounter = 0;
    6200        ulCounter < nLength;
    6201        ulCounter++)
    6202   {
    6203                                                 /* write character into cell */
    6204     *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
    6205                               (dwWriteCoord.X * 2)
    6206      ) = (UCHAR)wcCharacter;          /* @@@PH unicode to ascii conversion ! */
    6207 
    6208     dwWriteCoord.X++;                                 /* move write position */
    6209     if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
    6210     {
    6211       dwWriteCoord.X = 0;                               /* skip to next line */
    6212       dwWriteCoord.Y++;
    6213 
    6214                          /* oops, we're at the end of the buffer. Abort now. */
    6215       if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
    6216       {
    6217         if (lpNumberOfCharsWritten != NULL)       /* ensure pointer is valid */
    6218           *lpNumberOfCharsWritten = ulCounter;
    6219 
    6220                                           /* update screen if active console */
    6221         if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    6222           ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */
    6223 
    6224         return (TRUE);
    6225       }
    6226     }
    6227   }
    6228 
    6229                                           /* update screen if active console */
    6230   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    6231     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    6232 
    6233   if (lpNumberOfCharsWritten != NULL)             /* ensure pointer is valid */
    6234     *lpNumberOfCharsWritten = nLength;
    6235 
    6236   return (TRUE);
    6237 }
    6238 
    6239 
    6240 
    6241 /*****************************************************************************
    6242  * Name      : DWORD HMDeviceConsoleBufferClass::GetConsoleMode
    6243  * Purpose   : queries the current console mode
    6244  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6245  *             LPDWORD lpMode
    6246  * Variables :
    6247  * Result    :
    6248  * Remark    :
    6249  * Status    : UNTESTED
    6250  *
    6251  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6252  *****************************************************************************/
    6253 
    6254 DWORD HMDeviceConsoleBufferClass::GetConsoleMode(PHMHANDLEDATA pHMHandleData,
    6255                                                  LPDWORD       lpMode)
    6256 {
    6257   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6258 
    6259 #ifdef DEBUG_LOCAL2
    6260   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetConsoleMode(%08x,%08x).\n",
    6261            pHMHandleData,
    6262            lpMode);
    6263 #endif
    6264 
    6265   *lpMode = pConsoleBuffer->dwConsoleMode;    /* return current console mode */
    6266 
    6267   return (TRUE);
    6268 }
    6269 
    6270 
    6271 /*****************************************************************************
    6272  * Name      : DWORD HMDeviceConsoleBufferClass::GetConsoleCursorInfo
    6273  * Purpose   : queries the current console's cursor information
    6274  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6275  *             PCONSOLE_CURSOR_INFO pCCI
    6276  * Variables :
    6277  * Result    :
    6278  * Remark    :
    6279  * Status    : UNTESTED
    6280  *
    6281  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6282  *****************************************************************************/
    6283 
    6284 DWORD HMDeviceConsoleBufferClass::GetConsoleCursorInfo(PHMHANDLEDATA        pHMHandleData,
    6285                                                        PCONSOLE_CURSOR_INFO pCCI)
    6286 {
    6287   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6288 
    6289 #ifdef DEBUG_LOCAL2
    6290   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetConsoleCursorInfo(%08x,%08x).\n",
    6291            pHMHandleData,
    6292            pCCI);
    6293 #endif
    6294 
    6295   memcpy(pCCI,                      /* just copy the whole information block */
    6296          &pConsoleBuffer->CursorInfo,
    6297          sizeof (pConsoleBuffer->CursorInfo) );
    6298 
    6299   return (TRUE);
    6300 }
    6301 
    6302 
    6303 /*****************************************************************************
    6304  * Name      : DWORD HMDeviceConsoleBufferClass::GetConsoleScreenBufferInfo
    6305  * Purpose   : queries the current console screen buffer's info
    6306  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6307  *             PCONSOLE_SCREEN_BUFFER_INFO pCSBI
    6308  * Variables :
    6309  * Result    :
    6310  * Remark    :
    6311  * Status    : UNTESTED
    6312  *
    6313  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6314  *****************************************************************************/
    6315 
    6316 DWORD HMDeviceConsoleBufferClass::GetConsoleScreenBufferInfo(PHMHANDLEDATA               pHMHandleData,
    6317                                                              PCONSOLE_SCREEN_BUFFER_INFO pCSBI)
    6318 {
    6319   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6320 
    6321 #ifdef DEBUG_LOCAL2
    6322   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetConsoleScreenBufferInfo(%08x,%08x).\n",
    6323            pHMHandleData,
    6324            pCSBI);
    6325 #endif
    6326 
    6327   pCSBI->dwSize           = pConsoleBuffer->coordBufferSize;
    6328   pCSBI->dwCursorPosition = pConsoleBuffer->coordCursorPosition;
    6329   pCSBI->wAttributes      = (USHORT)pConsoleBuffer->ucDefaultAttribute;
    6330 
    6331   /* @@@PH unsure, but should be OK */
    6332   pCSBI->srWindow.Left   = pConsoleBuffer->coordWindowPosition.X;
    6333   pCSBI->srWindow.Top    = pConsoleBuffer->coordWindowPosition.Y;
    6334   pCSBI->srWindow.Right  = pConsoleBuffer->coordWindowPosition.X +
    6335                            pConsoleBuffer->coordWindowSize.X - 1;
    6336   pCSBI->srWindow.Bottom = pConsoleBuffer->coordWindowPosition.Y +
    6337                            pConsoleBuffer->coordWindowSize.Y - 1;
    6338 
    6339   pCSBI->dwMaximumWindowSize = pConsoleBuffer->coordBufferSize;
    6340 
    6341   return (TRUE);
    6342 }
    6343 
    6344 
    6345 /*****************************************************************************
    6346  * Name      : DWORD HMDeviceConsoleBufferClass::GetLargestConsoleWindowSize
    6347  * Purpose   : Determine maximum AVIO size
    6348  * Parameters:
    6349  * Variables :
    6350  * Result    :
    6351  * Remark    :
    6352  * Status    :
    6353  *
    6354  * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
    6355  *****************************************************************************/
    6356 
    6357 DWORD HMDeviceConsoleBufferClass::GetLargestConsoleWindowSize(PHMHANDLEDATA pHMHandleData)
    6358 {
    6359   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6360   COORD          coordSize;                             /* maximum avio size */
    6361   LONG           lScreenCX;                   /* width and height of display */
    6362   LONG           lScreenCY;
    6363   APIRET         rc;                                       /* API returncode */
    6364 
    6365 
    6366 #ifdef DEBUG_LOCAL
    6367   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::GetLargestConsoleWindowSize(%08x).\n",
    6368            pHMHandleData);
    6369 #endif
    6370 
    6371   /* @@@PH determine maximum console window size in characters
    6372     based on display size and current avio font */
    6373 
    6374   lScreenCX = WinQuerySysValue(HWND_DESKTOP,            /* query PM for that */
    6375                                SV_CXSCREEN);
    6376 
    6377   lScreenCY = WinQuerySysValue(HWND_DESKTOP,            /* query PM for that */
    6378                                SV_CYFULLSCREEN);
    6379 
    6380   if (rc != NO_ERROR)
    6381   {
    6382     WriteLog("KERNEL32/CONSOLE: VioGetDeviceCellSize failed with #%u.\n",
    6383              rc);
    6384 
    6385     return (FALSE);                                        /* say API failed */
    6386   }
    6387 
    6388   if ( (ConsoleGlobals.sCellCX == 0) ||          /* prevent division by zero */
    6389        (ConsoleGlobals.sCellCY == 0) )
    6390   {
    6391     WriteLog("KERNEL32/CONSOLE: VioGetDeviceCellSize returned 0 value.\n");
    6392 
    6393     return (FALSE);                                        /* say API failed */
    6394   }
    6395 
    6396   coordSize.X = lScreenCX / ConsoleGlobals.sCellCX;                            /* calculate */
    6397   coordSize.Y = lScreenCY / ConsoleGlobals.sCellCY;
    6398 
    6399                 /* these limitations are due to OS/2's current VIO subsystem */
    6400   coordSize.X = min(coordSize.X, MAX_OS2_COLUMNS);
    6401   coordSize.Y = min(coordSize.Y, MAX_OS2_ROWS);
    6402 
    6403   return (COORD2ULONG(coordSize));                           /* return value */
    6404 }
    6405 
    6406 
    6407 /*****************************************************************************
    6408  * Name      : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputA
    6409  * Purpose   : reads character and color attribute data from screen rectangle
    6410  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6411  *             PCHAR_INFO    pchiDestBuffer
    6412  *             COORD         coordDestBufferSize
    6413  *             COORD         coordDestBufferCoord
    6414  *             PSMALL_RECT   psrctSourceRect
    6415  * Variables :
    6416  * Result    :
    6417  * Remark    :
    6418  * Status    : UNTESTED
    6419  *
    6420  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6421  *****************************************************************************/
    6422 
    6423 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputA(PHMHANDLEDATA pHMHandleData,
    6424                                                      PCHAR_INFO    pchiDestBuffer,
    6425                                                      COORD         coordDestBufferSize,
    6426                                                      COORD         coordDestBufferCoord,
    6427                                                      PSMALL_RECT   psrctSourceRect)
    6428 {
    6429   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6430   ULONG ulX,  ulY;                          /* current coordinate to be read */
    6431   ULONG ulCX, ulCY;                       /* width and height of target area */
    6432   ULONG ulReadX, ulReadY;                      /* position data is read from */
    6433   WORD  wCell;                                        /* currently read data */
    6434 
    6435   PCHAR_INFO pchi;
    6436 
    6437 #ifdef DEBUG_LOCAL2
    6438   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputA(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
    6439            pHMHandleData,
    6440            pchiDestBuffer,
    6441            coordDestBufferSize.X,
    6442            coordDestBufferSize.Y,
    6443            coordDestBufferCoord.X,
    6444            coordDestBufferCoord.Y,
    6445            psrctSourceRect);
    6446 #endif
    6447 
    6448 
    6449   /* verify psrctSourceRect first */
    6450   psrctSourceRect->Left  = max(psrctSourceRect->Left,  0);
    6451   psrctSourceRect->Top   = max(psrctSourceRect->Top,   0);
    6452   psrctSourceRect->Right = min(psrctSourceRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
    6453   psrctSourceRect->Bottom= min(psrctSourceRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
    6454 
    6455                                                      /* verify target buffer */
    6456   if ( (coordDestBufferSize.X < coordDestBufferCoord.X) ||
    6457        (coordDestBufferSize.Y < coordDestBufferCoord.Y) )
    6458   {
    6459     SetLastError(ERROR_INVALID_PARAMETER);        /* set detailed error info */
    6460     return (FALSE);                                            /* API failed */
    6461   }
    6462 
    6463   ulCX = coordDestBufferSize.X - coordDestBufferCoord.X;
    6464   ulCY = coordDestBufferSize.Y - coordDestBufferCoord.Y;
    6465 
    6466   ulCX = min(ulCX, (psrctSourceRect->Right  - psrctSourceRect->Left));
    6467   ulCY = min(ulCY, (psrctSourceRect->Bottom - psrctSourceRect->Top));
    6468 
    6469                                   /* final calculation of the copy rectangle */
    6470   psrctSourceRect->Right  = psrctSourceRect->Left + ulCX;
    6471   psrctSourceRect->Bottom = psrctSourceRect->Top  + ulCY;
    6472 
    6473 
    6474   for (ulY = 0,
    6475        ulReadY = psrctSourceRect->Top;
    6476 
    6477        ulY <= ulCY;
    6478 
    6479        ulY++,
    6480        ulReadY++)
    6481   {
    6482     pchi = pchiDestBuffer + sizeof(CHAR_INFO) * coordDestBufferCoord.X
    6483                           + sizeof(CHAR_INFO) * (coordDestBufferCoord.Y + ulY)
    6484                             * coordDestBufferSize.X;
    6485     for (ulX = 0,
    6486          ulReadX = psrctSourceRect->Left;
    6487 
    6488          ulX <= ulCX;
    6489 
    6490          ulX++,
    6491          ulReadX++,
    6492          pchi++)
    6493     {
    6494                                                            /* read character */
    6495       wCell = *(pConsoleBuffer->ppszLine[ulReadY] + ulReadX * 2);
    6496 
    6497       pchi->Char.AsciiChar = (UCHAR)(wCell & 0x00FF);
    6498       pchi->Attributes     = wCell >> 8;
    6499     }
    6500   }
    6501 
    6502   return (TRUE);                                            /* OK, that's it */
    6503 }
    6504 
    6505 
    6506 /*****************************************************************************
    6507  * Name      : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputW
    6508  * Purpose   : reads character and color attribute data from screen rectangle
    6509  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6510  *             PCHAR_INFO    pchiDestBuffer
    6511  *             COORD         coordDestBufferSize
    6512  *             COORD         coordDestBufferCoord
    6513  *             PSMALL_RECT   psrctSourceRect
    6514  * Variables :
    6515  * Result    :
    6516  * Remark    :
    6517  * Status    : UNTESTED
    6518  *
    6519  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6520  *****************************************************************************/
    6521 
    6522 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputW(PHMHANDLEDATA pHMHandleData,
    6523                                                      PCHAR_INFO    pchiDestBuffer,
    6524                                                      COORD         coordDestBufferSize,
    6525                                                      COORD         coordDestBufferCoord,
    6526                                                      PSMALL_RECT   psrctSourceRect)
    6527 {
    6528   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6529   ULONG ulX,  ulY;                          /* current coordinate to be read */
    6530   ULONG ulCX, ulCY;                       /* width and height of target area */
    6531   ULONG ulReadX, ulReadY;                      /* position data is read from */
    6532   WORD  wCell;                                        /* currently read data */
    6533 
    6534   PCHAR_INFO pchi;
    6535 
    6536 #ifdef DEBUG_LOCAL2
    6537   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputW(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
    6538            pHMHandleData,
    6539            pchiDestBuffer,
    6540            coordDestBufferSize.X,
    6541            coordDestBufferSize.Y,
    6542            coordDestBufferCoord.X,
    6543            coordDestBufferCoord.Y,
    6544            psrctSourceRect);
    6545 #endif
    6546 
    6547 
    6548   /* verify psrctSourceRect first */
    6549   psrctSourceRect->Left  = max(psrctSourceRect->Left,  0);
    6550   psrctSourceRect->Top   = max(psrctSourceRect->Top,   0);
    6551   psrctSourceRect->Right = min(psrctSourceRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
    6552   psrctSourceRect->Bottom= min(psrctSourceRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
    6553 
    6554                                                      /* verify target buffer */
    6555   if ( (coordDestBufferSize.X < coordDestBufferCoord.X) ||
    6556        (coordDestBufferSize.Y < coordDestBufferCoord.Y) )
    6557   {
    6558     SetLastError(ERROR_INVALID_PARAMETER);        /* set detailed error info */
    6559     return (FALSE);                                            /* API failed */
    6560   }
    6561 
    6562   ulCX = coordDestBufferSize.X - coordDestBufferCoord.X;
    6563   ulCY = coordDestBufferSize.Y - coordDestBufferCoord.Y;
    6564 
    6565   ulCX = min(ulCX, (psrctSourceRect->Right  - psrctSourceRect->Left));
    6566   ulCY = min(ulCY, (psrctSourceRect->Bottom - psrctSourceRect->Top));
    6567 
    6568                                   /* final calculation of the copy rectangle */
    6569   psrctSourceRect->Right  = psrctSourceRect->Left + ulCX;
    6570   psrctSourceRect->Bottom = psrctSourceRect->Top  + ulCY;
    6571 
    6572 
    6573   for (ulY = 0,
    6574        ulReadY = psrctSourceRect->Top;
    6575 
    6576        ulY <= ulCY;
    6577 
    6578        ulY++,
    6579        ulReadY++)
    6580   {
    6581     pchi = pchiDestBuffer + sizeof(CHAR_INFO) * coordDestBufferCoord.X
    6582                           + sizeof(CHAR_INFO) * (coordDestBufferCoord.Y + ulY)
    6583                             * coordDestBufferSize.X;
    6584     for (ulX = 0,
    6585          ulReadX = psrctSourceRect->Left;
    6586 
    6587          ulX <= ulCX;
    6588 
    6589          ulX++,
    6590          ulReadX++,
    6591          pchi++)
    6592     {
    6593                                                            /* read character */
    6594       wCell = *(pConsoleBuffer->ppszLine[ulReadY] + ulReadX * 2);
    6595 
    6596                                                      /* @@@PH Ascii->Unicode */
    6597       pchi->Char.UnicodeChar = (UCHAR)(wCell & 0x00FF);
    6598       pchi->Attributes     = wCell >> 8;
    6599     }
    6600   }
    6601 
    6602   return (TRUE);                                            /* OK, that's it */
    6603 }
    6604 
    6605 
    6606 /*****************************************************************************
    6607  * Name      : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputAttribute
    6608  * Purpose   : read an array with specified attributes from the console
    6609  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6610  *             LPWORD        lpwAttribute
    6611  *             DWORD         cReadCells
    6612  *             COORD         dwReadCoord
    6613  *             LPDWORD       lpcNumberRead
    6614  * Variables :
    6615  * Result    :
    6616  * Remark    :
    6617  * Status    : UNTESTED
    6618  *
    6619  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6620  *****************************************************************************/
    6621 
    6622 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,
    6623                                                              LPWORD        lpwAttribute,
    6624                                                              DWORD         cReadCells,
    6625                                                              COORD         dwReadCoord,
    6626                                                              LPDWORD       lpcNumberRead)
    6627 {
    6628   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6629   ULONG          ulCounter;                     /* current character counter */
    6630 
    6631 #ifdef DEBUG_LOCAL2
    6632   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputAttribute(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",
    6633            pHMHandleData,
    6634            lpwAttribute,
    6635            cReadCells,
    6636            dwReadCoord.X,
    6637            dwReadCoord.Y,
    6638            lpcNumberRead);
    6639 #endif
    6640 
    6641   if ( (dwReadCoord.X < 0) ||
    6642        (dwReadCoord.Y < 0) )
    6643   {
    6644     if (lpcNumberRead != NULL)                       /* ensure pointer is valid */
    6645       *lpcNumberRead = 0;                            /* complete error handling */
    6646 
    6647     SetLastError(ERROR_INVALID_PARAMETER);
    6648     return (FALSE);
    6649   }
    6650 
    6651                                     /* check if dwReadCoord is within specs */
    6652   if ( (dwReadCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
    6653        (dwReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
    6654   {
    6655     if (lpcNumberRead != NULL)                       /* ensure pointer is valid */
    6656       *lpcNumberRead = 0;                            /* complete error handling */
    6657 
    6658     SetLastError(ERROR_INVALID_PARAMETER);
    6659     return (FALSE);
    6660   }
    6661 
    6662 
    6663                                         /* OK, now write the attribute lines */
    6664   for (ulCounter = 0;
    6665        ulCounter < cReadCells;
    6666        ulCounter++,
    6667        lpwAttribute++)
    6668   {
    6669                                                 /* write attribute into cell */
    6670     *lpwAttribute = (UCHAR)
    6671       *(pConsoleBuffer->ppszLine[dwReadCoord.Y] +
    6672                                 (dwReadCoord.X * 2 + 1));
    6673 
    6674     dwReadCoord.X++;                                 /* move write position */
    6675     if (dwReadCoord.X >= pConsoleBuffer->coordBufferSize.X)
    6676     {
    6677       dwReadCoord.X = 0;                               /* skip to next line */
    6678       dwReadCoord.Y++;
    6679 
    6680                          /* oops, we're at the end of the buffer. Abort now. */
    6681       if (dwReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
    6682       {
    6683         if (lpcNumberRead != NULL)                   /* ensure pointer is valid */
    6684           *lpcNumberRead = ulCounter;
    6685 
    6686         return (TRUE);
    6687       }
    6688     }
    6689   }
    6690 
    6691   if (lpcNumberRead != NULL)                         /* ensure pointer is valid */
    6692     *lpcNumberRead = cReadCells;
    6693 
    6694   return (TRUE);
    6695 }
    6696 
    6697 
    6698 /*****************************************************************************
    6699  * Name      : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterA
    6700  * Purpose   : read an array with specified characters from the console
    6701  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6702  *             LPWORD        lpReadBuffer
    6703  *             DWORD         cRead
    6704  *             COORD         coordReadCoord
    6705  *             LPDWORD       lpcNumberRead
    6706  * Variables :
    6707  * Result    :
    6708  * Remark    :
    6709  * Status    : UNTESTED
    6710  *
    6711  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6712  *****************************************************************************/
    6713 
    6714 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,
    6715                                                               LPTSTR        lpwReadBuffer,
    6716                                                               DWORD         cchRead,
    6717                                                               COORD         coordReadCoord,
    6718                                                               LPDWORD       lpcNumberRead)
    6719 {
    6720   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6721   ULONG          ulCounter;                     /* current character counter */
    6722 
    6723 #ifdef DEBUG_LOCAL2
    6724   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputCharacterA(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",
    6725            pHMHandleData,
    6726            lpwReadBuffer,
    6727            cchRead,
    6728            coordReadCoord.X,
    6729            coordReadCoord.Y,
    6730            lpcNumberRead);
    6731 #endif
    6732 
    6733   if ( (coordReadCoord.X < 0) ||
    6734        (coordReadCoord.Y < 0) )
    6735   {
    6736     if (lpcNumberRead != NULL)                    /* ensure pointer is valid */
    6737       *lpcNumberRead = 0;                         /* complete error handling */
    6738 
    6739     SetLastError(ERROR_INVALID_PARAMETER);
    6740     return (FALSE);
    6741   }
    6742 
    6743                                   /* check if coordReadCoord is within specs */
    6744   if ( (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
    6745        (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
    6746   {
    6747     if (lpcNumberRead != NULL)                    /* ensure pointer is valid */
    6748       *lpcNumberRead = 0;                         /* complete error handling */
    6749 
    6750     SetLastError(ERROR_INVALID_PARAMETER);
    6751     return (FALSE);
    6752   }
    6753 
    6754 
    6755                                         /* OK, now write the attribute lines */
    6756   for (ulCounter = 0;
    6757        ulCounter < cchRead;
    6758        ulCounter++,
    6759        lpwReadBuffer++)
    6760   {
    6761                                                 /* write character into cell */
    6762     *lpwReadBuffer =
    6763       *(pConsoleBuffer->ppszLine[coordReadCoord.Y] +
    6764                                 (coordReadCoord.X * 2));
    6765 
    6766     coordReadCoord.X++;                               /* move write position */
    6767     if (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X)
    6768     {
    6769       coordReadCoord.X = 0;                             /* skip to next line */
    6770       coordReadCoord.Y++;
    6771 
    6772                          /* oops, we're at the end of the buffer. Abort now. */
    6773       if (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
    6774       {
    6775         if (lpcNumberRead != NULL)                /* ensure pointer is valid */
    6776           *lpcNumberRead = ulCounter;
    6777 
    6778         return (TRUE);
    6779       }
    6780     }
    6781   }
    6782 
    6783   if (lpcNumberRead != NULL)                         /* ensure pointer is valid */
    6784     *lpcNumberRead = cchRead;
    6785 
    6786   return (TRUE);
    6787 }
    6788 
    6789 
    6790 /*****************************************************************************
    6791  * Name      : DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterW
    6792  * Purpose   : read an array with specified characters from the console
    6793  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    6794  *             LPWORD        lpReadBuffer
    6795  *             DWORD         cRead
    6796  *             COORD         coordReadCoord
    6797  *             LPDWORD       lpcNumberRead
    6798  * Variables :
    6799  * Result    :
    6800  * Remark    :
    6801  * Status    : UNTESTED
    6802  *
    6803  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6804  *****************************************************************************/
    6805 
    6806 DWORD HMDeviceConsoleBufferClass::ReadConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,
    6807                                                               LPWSTR        lpwReadBuffer,
    6808                                                               DWORD         cchRead,
    6809                                                               COORD         coordReadCoord,
    6810                                                               LPDWORD       lpcNumberRead)
    6811 {
    6812   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6813   ULONG          ulCounter;                     /* current character counter */
    6814 
    6815 #ifdef DEBUG_LOCAL2
    6816   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ReadConsoleOutputCharacterW(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",
    6817            pHMHandleData,
    6818            lpwReadBuffer,
    6819            cchRead,
    6820            coordReadCoord.X,
    6821            coordReadCoord.Y,
    6822            lpcNumberRead);
    6823 #endif
    6824 
    6825   if ( (coordReadCoord.X < 0) ||
    6826        (coordReadCoord.Y < 0) )
    6827   {
    6828     if (lpcNumberRead != NULL)                    /* ensure pointer is valid */
    6829       *lpcNumberRead = 0;                         /* complete error handling */
    6830 
    6831     SetLastError(ERROR_INVALID_PARAMETER);
    6832     return (FALSE);
    6833   }
    6834 
    6835                                   /* check if coordReadCoord is within specs */
    6836   if ( (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
    6837        (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
    6838   {
    6839     if (lpcNumberRead != NULL)                    /* ensure pointer is valid */
    6840       *lpcNumberRead = 0;                         /* complete error handling */
    6841 
    6842     SetLastError(ERROR_INVALID_PARAMETER);
    6843     return (FALSE);
    6844   }
    6845 
    6846 
    6847                                         /* OK, now write the attribute lines */
    6848   for (ulCounter = 0;
    6849        ulCounter < cchRead;
    6850        ulCounter++,
    6851        lpwReadBuffer++)
    6852   {
    6853     /* @@@PH Ascii -> Unicode translation */
    6854                                                 /* write character into cell */
    6855     *lpwReadBuffer =
    6856       *(pConsoleBuffer->ppszLine[coordReadCoord.Y] +
    6857                                 (coordReadCoord.X * 2));
    6858 
    6859     coordReadCoord.X++;                               /* move write position */
    6860     if (coordReadCoord.X >= pConsoleBuffer->coordBufferSize.X)
    6861     {
    6862       coordReadCoord.X = 0;                             /* skip to next line */
    6863       coordReadCoord.Y++;
    6864 
    6865                          /* oops, we're at the end of the buffer. Abort now. */
    6866       if (coordReadCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
    6867       {
    6868         if (lpcNumberRead != NULL)                /* ensure pointer is valid */
    6869           *lpcNumberRead = ulCounter;
    6870 
    6871         return (TRUE);
    6872       }
    6873     }
    6874   }
    6875 
    6876   if (lpcNumberRead != NULL)                         /* ensure pointer is valid */
    6877     *lpcNumberRead = cchRead;
    6878 
    6879   return (TRUE);
    6880 }
    6881 
    6882 
    6883 /*****************************************************************************
    6884  * Name      : DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferA
    6885  * Purpose   : move a block of data within the screen buffer
    6886  * Parameters: PHMHANDLEDATA pHMHandleData   - handle specific data
    6887  *             PSMALL_RECT   psrctSourceRect - source rectangle
    6888  *             PSMALL_RECT   psrctClipRect   - clipping rectangle
    6889  *             COORD         coordDestOrigin - destination coordinate
    6890  *             PCHAR_INFO    pchiFill        - fill character
    6891  * Variables :
    6892  * Result    :
    6893  * Remark    : Routine is subject to optimizations.
    6894  *             @@@PH rewrite -> faster, better handling of overlapped buffers
    6895  *                   copy srctSource to buffer, fill it with fill character
    6896  *                   copy buffer to srctDest ?
    6897  * Status    : UNTESTED
    6898  *
    6899  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    6900  *****************************************************************************/
    6901 
    6902 DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferA(PHMHANDLEDATA pHMHandleData,
    6903                                                              PSMALL_RECT   psrctSourceRect,
    6904                                                              PSMALL_RECT   psrctClipRect,
    6905                                                              COORD         coordDestOrigin,
    6906                                                              PCHAR_INFO    pchiFill)
    6907 {
    6908   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    6909   SMALL_RECT     srctView;            /* the actual rectangle of "happening" */
    6910   SMALL_RECT     srctSource;       /* the clipped source and dest rectangles */
    6911   SMALL_RECT     srctDest;
    6912   int            iX, iY;                             /* scan loop counters */
    6913   PUSHORT        pusTarget, pusSource;      /* pointer to source, dest cells */
    6914   WORD           wAttr;                      /* fill character and attribute */
    6915   int            iBlitDirection;             /* to handle overlapped buffers */
    6916 
    6917 #ifdef DEBUG_LOCAL2
    6918   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ScrollConsoleScreenBufferA(%08x,%08x,%08x,x=%u y=%u,%08x).\n",
    6919            pHMHandleData,
    6920            psrctSourceRect,
    6921            psrctClipRect,
    6922            coordDestOrigin.X,
    6923            coordDestOrigin.Y,
    6924            pchiFill);
    6925 #endif
    6926 
    6927                                    /* calculate effective clipping rectangle */
    6928   if (psrctClipRect != NULL)          /* if clipping rectangle was specified */
    6929   {
    6930     memcpy(&srctView,
    6931            psrctClipRect,
    6932            sizeof (SMALL_RECT) );
    6933 
    6934                                           /* check boundary with buffer size */
    6935     srctView.Left   = max(0, srctView.Left);
    6936     srctView.Top    = max(0, srctView.Top );
    6937     srctView.Right  = min(srctView.Right,  pConsoleBuffer->coordBufferSize.X);
    6938     srctView.Bottom = min(srctView.Bottom, pConsoleBuffer->coordBufferSize.Y);
    6939   }
    6940   else
    6941   {
    6942     srctView.Left   = 0;   /* buffer size is the maximum clipping rectangle */
    6943     srctView.Top    = 0;
    6944     srctView.Right  = pConsoleBuffer->coordBufferSize.X;
    6945     srctView.Bottom = pConsoleBuffer->coordBufferSize.Y;
    6946   }
    6947 
    6948   memcpy(&srctSource,                               /* copy source rectangle */
    6949          psrctSourceRect,
    6950          sizeof (srctSource) );
    6951                                    /* check boundary with clipping rectangle */
    6952   srctSource.Left   = max(srctSource.Left,  srctView.Left  );
    6953   srctSource.Top    = max(srctSource.Top,   srctView.Top   );
    6954   srctSource.Right  = min(srctSource.Right, srctView.Right );
    6955   srctSource.Bottom = min(srctSource.Bottom,srctView.Bottom);
    6956 
    6957   srctDest.Left  = max(srctView.Left,   coordDestOrigin.X);
    6958   srctDest.Top   = max(srctView.Top,    coordDestOrigin.Y);
    6959   srctDest.Right = min(srctView.Right,  srctDest.Left + srctSource.Right  - srctSource.Left);
    6960   srctDest.Bottom= min(srctView.Bottom, srctDest.Top  + srctSource.Bottom - srctSource.Top);
    6961 
    6962   /****************************
    6963    * first copy the rectangle *
    6964    ****************************/
    6965 
    6966   if (srctDest.Left >  srctSource.Left) iBlitDirection  = 0;
    6967   else                                  iBlitDirection  = 1;
    6968   if (srctDest.Top  >  srctSource.Top)  iBlitDirection += 2;
    6969 
    6970                                /* this leaves us with three different cases: */
    6971                                /*                                            */
    6972                                /* 0 - dest is to upper left of the source    */
    6973                                /* 1 - dest is to upper right of the source   */
    6974                                /* 2 - dest is to lower left of the source    */
    6975                                /* 3 - dest is to lower right of the source   */
    6976 
    6977   switch (iBlitDirection)
    6978   {
    6979     /**************
    6980      * upper left *
    6981      **************/
    6982     case 0:
    6983       for (iY = 0;
    6984            iY <= srctDest.Bottom - srctDest.Top;
    6985            iY++)
    6986       {
    6987                          /* calculate pointer to start of target screen line */
    6988         pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +
    6989                                (srctDest.Left << 1) );
    6990 
    6991                          /* calculate pointer to start of source screen line */
    6992         pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +
    6993                                (srctSource.Left << 1) );
    6994 
    6995         for (iX = srctDest.Left;
    6996              iX <= srctDest.Right;
    6997              iX++,
    6998              pusTarget++,
    6999              pusSource++)
    7000           *pusTarget = *pusSource;                         /* copy character */
    7001       }
    7002       break;
    7003 
    7004     /***************
    7005      * upper right *
    7006      ***************/
    7007     case 1:
    7008       for (iY = 0;
    7009            iY <= srctDest.Bottom - srctDest.Top;
    7010            iY++)
    7011       {
    7012                            /* calculate pointer to end of target screen line */
    7013         pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +
    7014                                ( srctDest.Right << 1) );
    7015 
    7016                            /* calculate pointer to end of source screen line */
    7017         pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +
    7018                                ( srctSource.Right << 1) );
    7019 
    7020         for (iX = srctDest.Right;
    7021              iX >= srctDest.Left;
    7022              iX--,
    7023              pusTarget--,
    7024              pusSource--)
    7025           *pusTarget = *pusSource;                         /* copy character */
    7026       }
    7027       break;
    7028 
    7029     /***************
    7030      * lower left  *
    7031      ***************/
    7032     case 2:
    7033       for (iY = srctDest.Bottom - srctDest.Top;
    7034            iY >= 0;
    7035            iY--)
    7036       {
    7037                          /* calculate pointer to start of target screen line */
    7038         pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +
    7039                                (srctDest.Left << 1) );
    7040 
    7041                          /* calculate pointer to start of source screen line */
    7042         pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +
    7043                                (srctSource.Left << 1) );
    7044 
    7045         for (iX = srctDest.Left;
    7046              iX <= srctDest.Right;
    7047              iX++,
    7048              pusTarget++,
    7049              pusSource++)
    7050           *pusTarget = *pusSource;                         /* copy character */
    7051       }
    7052       break;
    7053 
    7054     /****************
    7055      * lower right  *
    7056      ****************/
    7057     case 3:
    7058       for (iY = srctDest.Bottom - srctDest.Top;
    7059            iY >= 0;
    7060            iY--)
    7061       {
    7062                            /* calculate pointer to end of target screen line */
    7063         pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctDest.Top] +
    7064                                ( srctDest.Right << 1) );
    7065 
    7066                            /* calculate pointer to end of source screen line */
    7067         pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[iY + srctSource.Top] +
    7068                                (srctSource.Right << 1) );
    7069 
    7070         for (iX = srctDest.Right;
    7071              iX >= srctDest.Left;
    7072              iX--,
    7073              pusTarget--,
    7074              pusSource--)
    7075           *pusTarget = *pusSource;                         /* copy character */
    7076       }
    7077       break;
    7078   }
    7079 
    7080 
    7081               /* this is the character and attribute for the uncovered cells */
    7082   wAttr = (pchiFill->Char.AsciiChar) + (pchiFill->Attributes << 8);
    7083 
    7084   for (iY = srctSource.Top;            /* now fill uncovered area with pchi */
    7085        iY < srctSource.Bottom;
    7086        iY++)
    7087   {
    7088     pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[iY] + srctSource.Left);
    7089 
    7090     for (iX = srctSource.Left;
    7091          iX < srctSource.Right;
    7092          iX++,
    7093          pusTarget++)
    7094          /* check if covered by srctDest or not */
    7095       if ( (iY >= srctDest.Top)    &&
    7096            (iY <= srctDest.Bottom) &&
    7097            (iX >= srctDest.Left)   &&
    7098            (iX <= srctDest.Right)
    7099          )
    7100         ;                              /* should be faster for the optimizer */
    7101       else
    7102         *pusTarget = wAttr;            /* write fill character and attribute */
    7103   }
    7104 
    7105                                           /* update screen if active console */
    7106   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    7107     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    7108 
    7109   return (TRUE);
    7110 }
    7111 
    7112 
    7113 /*****************************************************************************
    7114  * Name      : DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferW
    7115  * Purpose   : move a block of data within the screen buffer
    7116 
    7117 
    7118  * Parameters: PHMHANDLEDATA pHMHandleData   - handle specific data
    7119  *             PSMALL_RECT   psrctSourceRect - source rectangle
    7120  *             PSMALL_RECT   psrctClipRect   - clipping rectangle
    7121  *             COORD         coordDestOrigin - destination coordinate
    7122  *             PCHAR_INFO    pchiFill        - fill character
    7123  * Variables :
    7124  * Result    :
    7125  * Remark    : Routine is subject to optimizations.
    7126  * Status    : UNTESTED
    7127  *
    7128  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7129  *****************************************************************************/
    7130 
    7131 DWORD HMDeviceConsoleBufferClass::ScrollConsoleScreenBufferW(PHMHANDLEDATA pHMHandleData,
    7132                                                              PSMALL_RECT   psrctSourceRect,
    7133                                                              PSMALL_RECT   psrctClipRect,
    7134                                                              COORD         coordDestOrigin,
    7135                                                              PCHAR_INFO    pchiFill)
    7136 {
    7137   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7138   SMALL_RECT     srctView;            /* the actual rectangle of "happening" */
    7139   SMALL_RECT     srctSource;       /* the clipped source and dest rectangles */
    7140   SMALL_RECT     srctDest;
    7141   ULONG          ulX, ulY;                             /* scan loop counters */
    7142   PUSHORT        pusTarget, pusSource;      /* pointer to source, dest cells */
    7143   WORD           wAttr;                      /* fill character and attribute */
    7144 
    7145 #ifdef DEBUG_LOCAL2
    7146   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::ScrollConsoleScreenBufferW(%08x,%08x,%08x,x=%u y=%u,%08x).\n",
    7147            pHMHandleData,
    7148            psrctSourceRect,
    7149            psrctClipRect,
    7150            coordDestOrigin.X,
    7151            coordDestOrigin.Y,
    7152            pchiFill);
    7153 #endif
    7154 
    7155                                    /* calculate effective clipping rectangle */
    7156   if (psrctClipRect != NULL)          /* if clipping rectangle was specified */
    7157   {
    7158     memcpy(&srctView,
    7159            psrctClipRect,
    7160            sizeof (SMALL_RECT) );
    7161 
    7162                                           /* check boundary with buffer size */
    7163     srctView.Left   = max(0, srctView.Left);
    7164     srctView.Top    = max(0, srctView.Top );
    7165     srctView.Right  = min(srctView.Right,  pConsoleBuffer->coordBufferSize.X);
    7166     srctView.Bottom = min(srctView.Bottom, pConsoleBuffer->coordBufferSize.Y);
    7167   }
    7168   else
    7169   {
    7170     srctView.Left   = 0;   /* buffer size is the maximum clipping rectangle */
    7171     srctView.Top    = 0;
    7172     srctView.Right  = pConsoleBuffer->coordBufferSize.X;
    7173     srctView.Bottom = pConsoleBuffer->coordBufferSize.Y;
    7174   }
    7175 
    7176   memcpy(&srctSource,                               /* copy source rectangle */
    7177          psrctSourceRect,
    7178          sizeof (srctSource) );
    7179                                    /* check boundary with clipping rectangle */
    7180   srctSource.Left   = max(srctSource.Left,  srctView.Left  );
    7181   srctSource.Top    = max(srctSource.Top,   srctView.Top   );
    7182   srctSource.Right  = min(srctSource.Right, srctView.Right );
    7183   srctSource.Bottom = min(srctSource.Bottom,srctView.Bottom);
    7184 
    7185   srctDest.Left  = max(srctView.Left,   coordDestOrigin.X);
    7186   srctDest.Top   = max(srctView.Top,    coordDestOrigin.Y);
    7187   srctDest.Right = min(srctView.Right,  srctDest.Left + srctSource.Right  - srctSource.Left);
    7188   srctDest.Bottom= min(srctView.Bottom, srctDest.Top  + srctSource.Bottom - srctSource.Top);
    7189 
    7190   /* first copy the rectangle */
    7191   for (ulY = 0;
    7192        ulY < srctDest.Bottom - srctDest.Top;
    7193        ulY++)
    7194   {
    7195                          /* calculate pointer to start of target screen line */
    7196     pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[ulY + srctDest.Top] +
    7197                            srctDest.Left);
    7198 
    7199                          /* calculate pointer to start of source screen line */
    7200     pusSource = (PUSHORT) (pConsoleBuffer->ppszLine[ulY + srctSource.Top] +
    7201                            srctSource.Left);
    7202 
    7203     for (ulX = srctDest.Left;
    7204          ulX < srctDest.Right;
    7205          ulX++,
    7206          pusTarget++,
    7207          pusSource++)
    7208       *pusTarget = *pusSource;                             /* copy character */
    7209   }
    7210 
    7211 
    7212               /* this is the character and attribute for the uncovered cells */
    7213   /* @@@PH Unicode->Ascii translation */
    7214   wAttr = (pchiFill->Char.UnicodeChar) + (pchiFill->Attributes << 8);
    7215 
    7216   for (ulY = srctSource.Top;            /* now fill uncovered area with pchi */
    7217        ulY < srctSource.Bottom;
    7218        ulY++)
    7219   {
    7220     pusTarget = (PUSHORT) (pConsoleBuffer->ppszLine[ulY] + srctSource.Left);
    7221 
    7222     for (ulX = srctSource.Left;
    7223          ulX < srctSource.Right;
    7224          ulX++,
    7225          pusTarget++)
    7226       *pusTarget = wAttr;              /* write fill character and attribute */
    7227   }
    7228 
    7229                                           /* update screen if active console */
    7230   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    7231     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    7232 
    7233   return (TRUE);
    7234 }
    7235 
    7236 
    7237 /*****************************************************************************
    7238  * Name      : DWORD HMDeviceConsoleBufferClass::SetConsoleCursorInfo
    7239  * Purpose   : sets the current console's cursor information
    7240  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7241  *             PCONSOLE_CURSOR_INFO pCCI
    7242  * Variables :
    7243  * Result    :
    7244  * Remark    :
    7245  * Status    : UNTESTED
    7246  *
    7247  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7248  *****************************************************************************/
    7249 
    7250 DWORD HMDeviceConsoleBufferClass::SetConsoleCursorInfo(PHMHANDLEDATA        pHMHandleData,
    7251                                                        PCONSOLE_CURSOR_INFO pCCI)
    7252 {
    7253   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7254 
    7255 #ifdef DEBUG_LOCAL2
    7256   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleCursorInfo(%08x,%08x).\n",
    7257            pHMHandleData,
    7258            pCCI);
    7259 #endif
    7260 
    7261                                                        /* validate structure */
    7262   if ( (pCCI->dwSize < 1) ||
    7263        (pCCI->dwSize > 100) )
    7264   {
    7265     SetLastError(ERROR_INVALID_PARAMETER);        /* set extended error info */
    7266     return (FALSE);                                            /* API failed */
    7267   }
    7268 
    7269               /* if we're the active buffer, remove cursor from screen first */
    7270   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    7271     ConsoleCursorShow(pConsoleBuffer,
    7272                       CONSOLECURSOR_HIDE);
    7273 
    7274   memcpy(&pConsoleBuffer->CursorInfo,    /* copy the whole information block */
    7275          pCCI,
    7276          sizeof (pConsoleBuffer->CursorInfo) );
    7277 
    7278   return (TRUE);
    7279 }
    7280 
    7281 
    7282 /*****************************************************************************
    7283  * Name      : DWORD HMDeviceConsoleBufferClass::SetConsoleCursorPosition
    7284  * Purpose   : sets the current console's cursor position
    7285  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7286  *             COORD         coordCursorPosition
    7287  * Variables :
    7288  * Result    :
    7289  * Remark    :
    7290  * Status    : UNTESTED
    7291  *
    7292  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7293  *****************************************************************************/
    7294 
    7295 DWORD HMDeviceConsoleBufferClass::SetConsoleCursorPosition(PHMHANDLEDATA pHMHandleData,
    7296                                                            COORD         coordCursorPosition)
    7297 {
    7298   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7299 
    7300 #ifdef DEBUG_LOCAL2
    7301   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleCursorPosition(%08x,x=%u.y=%u).\n",
    7302            pHMHandleData,
    7303            coordCursorPosition.X,
    7304            coordCursorPosition.Y);
    7305 #endif
    7306 
    7307                                   /* @@@PH remove cursor from screen first ! */
    7308   pConsoleBuffer->coordCursorPosition = coordCursorPosition;
    7309 
    7310   return (TRUE);
    7311 }
    7312 
    7313 
    7314 /*****************************************************************************
    7315  * Name      : DWORD HMDeviceConsoleBufferClass::SetConsoleMode
    7316  * Purpose   : sets the current console mode
    7317  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7318  *             DWORD         dwMode        - console mode
    7319  * Variables :
    7320  * Result    :
    7321  * Remark    :
    7322  * Status    : UNTESTED
    7323  *
    7324  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7325  *****************************************************************************/
    7326 
    7327 DWORD HMDeviceConsoleBufferClass::SetConsoleMode(PHMHANDLEDATA pHMHandleData,
    7328                                                  DWORD         dwMode)
    7329 {
    7330   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7331 
    7332 #ifdef DEBUG_LOCAL2
    7333   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleMode(%08x,%08x).\n",
    7334            pHMHandleData,
    7335            dwMode);
    7336 #endif
    7337 
    7338   pConsoleBuffer->dwConsoleMode = dwMode;        /* set current console mode */
    7339 
    7340   return (TRUE);
    7341 }
    7342 
    7343 
    7344 /*****************************************************************************
    7345  * Name      : DWORD HMDeviceConsoleBufferClass::SetConsoleScreenBufferSize
    7346  * Purpose   : allocate or re-allocate the screenbuffer and transform the
    7347  *             old buffer as required
    7348  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7349  *             COORD         coordSize     - the new buffer size
    7350  * Variables :
    7351  * Result    :
    7352  * Remark    :
    7353  * Status    : UNTESTED
    7354  *
    7355  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7356  *****************************************************************************/
    7357 
    7358 DWORD HMDeviceConsoleBufferClass::SetConsoleScreenBufferSize (PHMHANDLEDATA pHMHandleData,
    7359                                                               COORD         coordSize)
    7360 {
    7361   ULONG ulSize;                         /* calculated size of the new buffer */
    7362   PSZ  *ppszNew;                                 /* pointer to the new array */
    7363   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7364   ULONG ulLine;                                        /* line index counter */
    7365 
    7366 #ifdef DEBUG_LOCAL2
    7367   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleScreenBufferSize(%u,%u).\n",
    7368            coordSize.X,
    7369            coordSize.Y);
    7370 #endif
    7371 
    7372 
    7373                                  /* re-allocate the whole line-pointer array */
    7374   ulSize = coordSize.Y * (coordSize.X * 2 + sizeof (PSZ) );
    7375   if (ulSize == 0)                          /* set new buffer size to zero ? */
    7376   {
    7377     if (pConsoleBuffer->ppszLine != NULL)        /* if old buffer is present */
    7378       free (pConsoleBuffer->ppszLine);                    /* free old buffer */
    7379 
    7380     pConsoleBuffer->ppszLine          = NULL;
    7381     pConsoleBuffer->coordBufferSize.X = 0;
    7382     pConsoleBuffer->coordBufferSize.Y = 0;
    7383     pConsoleBuffer->coordWindowSize.X = 0;
    7384     pConsoleBuffer->coordWindowSize.Y = 0;
    7385     pConsoleBuffer->coordWindowPosition.X = 0;
    7386     pConsoleBuffer->coordWindowPosition.Y = 0;
    7387 
    7388     return (TRUE);                                                     /* OK */
    7389   }
    7390 
    7391 
    7392   ppszNew = (PSZ *) malloc(ulSize);                        /* allocate array */
    7393   if (ppszNew == NULL)                            /* check proper allocation */
    7394   {
    7395     SetLastError(ERROR_NOT_ENOUGH_MEMORY);          /* set error information */
    7396     return (FALSE);                                 /* raise error condition */
    7397   }
    7398 
    7399 
    7400   for (ulLine = 0;                               /* setup line pointer array */
    7401        ulLine < coordSize.Y;
    7402        ulLine++)
    7403   {
    7404                                                    /* calculate line pointer */
    7405     ulSize = (ULONG)ppszNew + (coordSize.Y * sizeof(PSZ) )
    7406                             + (coordSize.X * ulLine * 2);
    7407     ppszNew[ulLine] = (PSZ)ulSize;                /* OK, write index pointer */
    7408   }
    7409 
    7410   ulSize     = ( ((ULONG)(pConsoleBuffer->ucDefaultAttribute) << 8) +
    7411                  ((ULONG)' ') +
    7412                  ((ULONG)(pConsoleBuffer->ucDefaultAttribute) << 24) +
    7413                  ((ULONG)' ' << 16) );
    7414 
    7415                                                     /* scroll the line index */
    7416   for (ulLine = 0;
    7417        ulLine < coordSize.Y;
    7418        ulLine++)
    7419     ConsoleBufferFillLine(ulSize,
    7420                           (PUSHORT)(ppszNew[ulLine]),
    7421                           coordSize.X);
    7422 
    7423 
    7424 
    7425                                                    /* copy lines as required */
    7426   if (pConsoleBuffer->ppszLine != NULL)         /* previous buffer present ? */
    7427   {
    7428     ULONG x, y;
    7429 
    7430                                           /* copy old characters as required */
    7431     x = min(pConsoleBuffer->coordBufferSize.X, coordSize.X);
    7432     y = min(pConsoleBuffer->coordBufferSize.Y, coordSize.Y);
    7433 
    7434     for (ulLine = 0;                                    /* copy line by line */
    7435          ulLine < y;
    7436          ulLine++)
    7437       memcpy(ppszNew[ulLine],
    7438              pConsoleBuffer->ppszLine[ulLine],
    7439              x * 2);
    7440 
    7441     free (pConsoleBuffer->ppszLine);    /* free previous screen buffer array */
    7442   }
    7443 
    7444 
    7445   pConsoleBuffer->ppszLine          = ppszNew;     /* poke in the new values */
    7446   pConsoleBuffer->coordBufferSize.X = coordSize.X;
    7447   pConsoleBuffer->coordBufferSize.Y = coordSize.Y;
    7448   pConsoleBuffer->coordCursorPosition.X = 0;
    7449   pConsoleBuffer->coordCursorPosition.Y = 0;
    7450 
    7451   /* @@@PH to be changed ! */
    7452   pConsoleBuffer->coordWindowSize.X = coordSize.X;                /* default */
    7453   pConsoleBuffer->coordWindowSize.Y = coordSize.Y;
    7454   pConsoleBuffer->coordWindowPosition.X = 0;
    7455   pConsoleBuffer->coordWindowPosition.Y = 0;
    7456 
    7457                                           /* update screen if active console */
    7458   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    7459     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    7460 
    7461   return TRUE;
    7462 }
    7463 
    7464 
    7465 /*****************************************************************************
    7466  * Name      :
    7467  * Purpose   :
    7468  * Parameters:
    7469  * Variables :
    7470  * Result    :
    7471  * Remark    :
    7472  * Status    :
    7473  *
    7474  * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
    7475  *****************************************************************************/
    7476 
    7477 DWORD HMDeviceConsoleBufferClass::SetConsoleTextAttribute(PHMHANDLEDATA pHMHandleData,
    7478                                                           WORD          wAttr)
    7479 {
    7480   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7481 
    7482 #ifdef DEBUG_LOCAL2
    7483   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleTextAttribute(%u).\n",
    7484            wAttr);
    7485 #endif
    7486 
    7487   pConsoleBuffer->ucDefaultAttribute = (UCHAR)wAttr;
    7488   return (TRUE);
    7489 }
    7490 
    7491 
    7492 /*****************************************************************************
    7493  * Name      :
    7494  * Purpose   :
    7495  * Parameters:
    7496  * Variables :
    7497  * Result    :
    7498  * Remark    :
    7499  * Status    :
    7500  *
    7501  * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
    7502  *****************************************************************************/
    7503 
    7504 DWORD HMDeviceConsoleBufferClass::SetConsoleActiveScreenBuffer(PHMHANDLEDATA pHMHandleData)
    7505 {
    7506   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7507 
    7508 #ifdef DEBUG_LOCAL
    7509   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleActiveScreenBuffer().\n");
    7510 #endif
    7511 
    7512                               /* set new buffer handle to the global console */
    7513   ConsoleGlobals.hConsoleBuffer  = pHMHandleData->hHandle;
    7514   ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    7515 
    7516   return (TRUE);
    7517 }
    7518 
    7519 
    7520 /*****************************************************************************
    7521  * Name      : BOOL HMDeviceConsoleBufferClass::SetConsoleWindowInfo
    7522  * Purpose   : set a new size to the console window
    7523  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7524  *             BOOL          fAbsolute
    7525  *             PSMALL_RECT   psrctWindowRect
    7526  * Variables :
    7527  * Result    :
    7528  * Remark    :
    7529  * Status    : UNTESTED
    7530  *
    7531  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7532  *****************************************************************************/
    7533 
    7534 BOOL HMDeviceConsoleBufferClass::SetConsoleWindowInfo(PHMHANDLEDATA pHMHandleData,
    7535                                                       BOOL          fAbsolute,
    7536                                                       PSMALL_RECT   psrctWindowRect)
    7537 {
    7538   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7539 
    7540 #ifdef DEBUG_LOCAL2
    7541   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::SetConsoleWindowInfo(%08x,%u,%08x).\n",
    7542            pHMHandleData,
    7543            fAbsolute,
    7544            psrctWindowRect);
    7545 #endif
    7546 
    7547   if (fAbsolute == TRUE)                  /* absolute coordinates provided ? */
    7548   {
    7549     if ( (psrctWindowRect->Left   < 0) ||          /* check parameters first */
    7550          (psrctWindowRect->Top    < 0) ||
    7551          (psrctWindowRect->Right  < 0) ||
    7552          (psrctWindowRect->Bottom < 0) ||
    7553          (psrctWindowRect->Right  <= psrctWindowRect->Left) ||
    7554          (psrctWindowRect->Bottom <= psrctWindowRect->Top)
    7555        )
    7556     {
    7557       SetLastError(ERROR_INVALID_PARAMETER);        /* set error information */
    7558       return (FALSE);                                               /* error */
    7559     }
    7560 
    7561                                  /* check we don't go beyond screen buffer ! */
    7562     if ( ((psrctWindowRect->Right  - psrctWindowRect->Left) > pConsoleBuffer->coordBufferSize.X) ||
    7563          ((psrctWindowRect->Bottom - psrctWindowRect->Top ) > pConsoleBuffer->coordBufferSize.Y) ||
    7564          (psrctWindowRect->Left >= pConsoleBuffer->coordBufferSize.X) ||
    7565          (psrctWindowRect->Top  >= pConsoleBuffer->coordBufferSize.Y)
    7566        )
    7567     {
    7568       SetLastError(ERROR_INVALID_PARAMETER);        /* set error information */
    7569       return (FALSE);                                               /* error */
    7570     }
    7571 
    7572     pConsoleBuffer->coordWindowSize.X     = psrctWindowRect->Right -
    7573                                             psrctWindowRect->Left;
    7574     pConsoleBuffer->coordWindowSize.Y     = psrctWindowRect->Bottom -
    7575                                             psrctWindowRect->Top;
    7576 
    7577     pConsoleBuffer->coordWindowPosition.X = psrctWindowRect->Left;
    7578     pConsoleBuffer->coordWindowPosition.Y = psrctWindowRect->Top;
    7579   }
    7580   else
    7581   {
    7582     int iSizeX;                                      /* relative coordinates */
    7583     int iSizeY;
    7584     int iPosX;
    7585     int iPosY;
    7586 
    7587     iSizeX = pConsoleBuffer->coordWindowSize.X + psrctWindowRect->Left + psrctWindowRect->Right;
    7588     iSizeY = pConsoleBuffer->coordWindowSize.Y + psrctWindowRect->Top  + psrctWindowRect->Bottom;
    7589     iPosX  = pConsoleBuffer->coordWindowPosition.X  + psrctWindowRect->Left;
    7590     iPosY  = pConsoleBuffer->coordWindowPosition.Y  + psrctWindowRect->Top;
    7591 
    7592                                  /* check we don't go beyond screen buffer ! */
    7593     if ( (iSizeX > pConsoleBuffer->coordBufferSize.X) ||
    7594          (iSizeY > pConsoleBuffer->coordBufferSize.Y) ||
    7595          (iPosX >= pConsoleBuffer->coordBufferSize.X) ||
    7596          (iPosY >= pConsoleBuffer->coordBufferSize.Y) ||
    7597          (iSizeX < 0) ||
    7598          (iSizeY < 0) ||
    7599          (iPosX  < 0) ||
    7600          (iPosY  < 0)
    7601        )
    7602     {
    7603       SetLastError(ERROR_INVALID_PARAMETER);        /* set error information */
    7604       return (FALSE);                                               /* error */
    7605     }
    7606 
    7607                                        /* Values are verified for being OK ! */
    7608     pConsoleBuffer->coordWindowPosition.X  = iPosX;
    7609     pConsoleBuffer->coordWindowPosition.Y  = iPosY;
    7610     pConsoleBuffer->coordWindowSize.X = iSizeX;
    7611     pConsoleBuffer->coordWindowSize.Y = iSizeY;
    7612   }
    7613 
    7614   /* update window */
    7615   /* @@@PH
    7616 
    7617    ConsoleWindowResize(COORD coordWindowSize,
    7618                        COORD coordWindowPos,
    7619 
    7620    */
    7621 
    7622                                           /* update window contents (scroll) */
    7623                                           /* update screen if active console */
    7624   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    7625     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    7626 
    7627   return (TRUE);                                                       /* OK */
    7628 }
    7629 
    7630 
    7631 /*****************************************************************************
    7632  * Name      : DWORD HMDeviceConsoleBufferClass::WriteConsoleA
    7633  * Purpose   : write a string to the console
    7634  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7635  *             LPWORD        lpwAttribute
    7636  *             DWORD         cWriteCells
    7637  *             COORD         dwWriteCoord
    7638  *             LPDWORD       lpcWritten
    7639  * Variables :
    7640  * Result    :
    7641  * Remark    :
    7642  * Status    : UNTESTED
    7643  *
    7644  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7645  *****************************************************************************/
    7646 
    7647 DWORD HMDeviceConsoleBufferClass::WriteConsoleA(PHMHANDLEDATA pHMHandleData,
    7648                                                 CONST VOID*   lpvBuffer,
    7649                                                 DWORD         cchToWrite,
    7650                                                 LPDWORD       lpcchWritten,
    7651                                                 LPVOID        lpvReserved)
    7652 {
    7653   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7654 
    7655 #ifdef DEBUG_LOCAL2
    7656   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleA(%08x,%08x,%u,%08x,%08x).\n",
    7657            pHMHandleData,
    7658            lpvBuffer,
    7659            cchToWrite,
    7660            lpcchWritten,
    7661            lpvReserved);
    7662 #endif
    7663 
    7664   /* simply forward the request to that routine */
    7665   return (HMDeviceConsoleBufferClass::WriteFile(pHMHandleData,
    7666                                                 lpvBuffer,
    7667                                                 cchToWrite,
    7668                                                 lpcchWritten,
    7669                                                 NULL));
    7670 }
    7671 
    7672 
    7673 /*****************************************************************************
    7674  * Name      : DWORD HMDeviceConsoleBufferClass::WriteConsoleW
    7675  * Purpose   : write a string to the console
    7676  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7677  *             LPWORD        lpwAttribute
    7678  *             DWORD         cWriteCells
    7679  *             COORD         dwWriteCoord
    7680  *             LPDWORD       lpcWritten
    7681  * Variables :
    7682  * Result    :
    7683  * Remark    :
    7684  * Status    : UNTESTED
    7685  *
    7686  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7687  *****************************************************************************/
    7688 
    7689 DWORD HMDeviceConsoleBufferClass::WriteConsoleW(PHMHANDLEDATA pHMHandleData,
    7690                                                 CONST VOID*   lpvBuffer,
    7691                                                 DWORD         cchToWrite,
    7692                                                 LPDWORD       lpcchWritten,
    7693                                                 LPVOID        lpvReserved)
    7694 {
    7695   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7696 
    7697 #ifdef DEBUG_LOCAL2
    7698   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleW(%08x,%08x,%u,%08x,%08x).\n",
    7699            pHMHandleData,
    7700            lpvBuffer,
    7701            cchToWrite,
    7702            lpcchWritten,
    7703            lpvReserved);
    7704 #endif
    7705 
    7706   /* @@@PH AScii -> unicode translation */
    7707 
    7708   /* simply forward the request to that routine */
    7709   return (HMDeviceConsoleBufferClass::WriteFile(pHMHandleData,
    7710                                                 lpvBuffer,
    7711                                                 cchToWrite,
    7712                                                 lpcchWritten,
    7713                                                 NULL));
    7714 }
    7715 
    7716 
    7717 /*****************************************************************************
    7718  * Name      : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputA
    7719  * Purpose   : write character and color attribute data to screen rectangle
    7720  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7721  *             PCHAR_INFO    pchiSrcBuffer
    7722  *             COORD         coordSrcBufferSize
    7723  *             COORD         coordSrcBufferCoord
    7724  *             PSMALL_RECT   psrctDestRect
    7725  * Variables :
    7726  * Result    :
    7727  * Remark    :
    7728  * Status    : UNTESTED
    7729  *
    7730  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7731  *****************************************************************************/
    7732 
    7733 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputA(PHMHANDLEDATA pHMHandleData,
    7734                                                       PCHAR_INFO    pchiSrcBuffer,
    7735                                                       COORD         coordSrcBufferSize,
    7736                                                       COORD         coordSrcBufferCoord,
    7737                                                       PSMALL_RECT   psrctDestRect)
    7738 {
    7739   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7740   ULONG ulX,      ulY;                      /* current coordinate to be read */
    7741   ULONG ulCX,     ulCY;                   /* width and height of target area */
    7742   ULONG ulWriteX, ulWriteY;                    /* position data is read from */
    7743   WORD  wCell;                                        /* currently read data */
    7744 
    7745   PCHAR_INFO pchi;
    7746   PSZ        pszTarget;
    7747 
    7748 #ifdef DEBUG_LOCAL2
    7749   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputA(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
    7750            pHMHandleData,
    7751            pchiSrcBuffer,
    7752            coordSrcBufferSize.X,
    7753            coordSrcBufferSize.Y,
    7754            coordSrcBufferCoord.X,
    7755            coordSrcBufferCoord.Y,
    7756            psrctDestRect);
    7757 #endif
    7758 
    7759 
    7760   /* verify psrctDestRect first */
    7761   psrctDestRect->Left  = max(psrctDestRect->Left,  0);
    7762   psrctDestRect->Top   = max(psrctDestRect->Top,   0);
    7763   psrctDestRect->Right = min(psrctDestRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
    7764   psrctDestRect->Bottom= min(psrctDestRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
    7765 
    7766                                                      /* verify target buffer */
    7767   if ( (coordSrcBufferSize.X < coordSrcBufferCoord.X) ||
    7768        (coordSrcBufferSize.Y < coordSrcBufferCoord.Y) )
    7769   {
    7770     SetLastError(ERROR_INVALID_PARAMETER);        /* set detailed error info */
    7771     return (FALSE);                                            /* API failed */
    7772   }
    7773 
    7774   ulCX = coordSrcBufferSize.X - coordSrcBufferCoord.X;
    7775   ulCY = coordSrcBufferSize.Y - coordSrcBufferCoord.Y;
    7776 
    7777   ulCX = min(ulCX, (psrctDestRect->Right  - psrctDestRect->Left));
    7778   ulCY = min(ulCY, (psrctDestRect->Bottom - psrctDestRect->Top));
    7779 
    7780                                   /* final calculation of the copy rectangle */
    7781   psrctDestRect->Right  = psrctDestRect->Left + ulCX;
    7782   psrctDestRect->Bottom = psrctDestRect->Top  + ulCY;
    7783 
    7784 
    7785   for (ulY = 0,
    7786        ulWriteY = psrctDestRect->Top;
    7787 
    7788        ulY <= ulCY;
    7789 
    7790        ulY++,
    7791        ulWriteY++)
    7792   {
    7793     pchi = pchiSrcBuffer + sizeof(CHAR_INFO) * coordSrcBufferCoord.X
    7794                           + sizeof(CHAR_INFO) * (coordSrcBufferCoord.Y + ulY)
    7795                             * coordSrcBufferSize.X;
    7796 
    7797                                 /* calculate pointer to start of screen line */
    7798     pszTarget = pConsoleBuffer->ppszLine[ulWriteY] + psrctDestRect->Left;
    7799 
    7800     for (ulX = 0,
    7801          ulWriteX = psrctDestRect->Left;
    7802 
    7803          ulX <= ulCX;
    7804 
    7805          ulX++,
    7806          ulWriteX++,
    7807          pchi++)
    7808     {
    7809                                             /* write character and attribute */
    7810       *pszTarget++ = (UCHAR)pchi->Char.AsciiChar;
    7811       *pszTarget++ = (UCHAR)pchi->Attributes;
    7812     }
    7813   }
    7814 
    7815                                           /* update screen if active console */
    7816   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    7817     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    7818 
    7819   return (TRUE);                                            /* OK, that's it */
    7820 }
    7821 
    7822 
    7823 /*****************************************************************************
    7824  * Name      : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputW
    7825  * Purpose   : write character and color attribute data to screen rectangle
    7826  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7827  *             PCHAR_INFO    pchiSrcBuffer
    7828  *             COORD         coordSrcBufferSize
    7829  *             COORD         coordSrcBufferCoord
    7830  *             PSMALL_RECT   psrctDestRect
    7831  * Variables :
    7832  * Result    :
    7833  * Remark    :
    7834  * Status    : UNTESTED
    7835  *
    7836  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7837  *****************************************************************************/
    7838 
    7839 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputW(PHMHANDLEDATA pHMHandleData,
    7840                                                       PCHAR_INFO    pchiSrcBuffer,
    7841                                                       COORD         coordSrcBufferSize,
    7842                                                       COORD         coordSrcBufferCoord,
    7843                                                       PSMALL_RECT   psrctDestRect)
    7844 {
    7845   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7846   ULONG ulX,      ulY;                      /* current coordinate to be read */
    7847   ULONG ulCX,     ulCY;                   /* width and height of target area */
    7848   ULONG ulWriteX, ulWriteY;                    /* position data is read from */
    7849   WORD  wCell;                                        /* currently read data */
    7850 
    7851   PCHAR_INFO pchi;
    7852   PSZ        pszTarget;
    7853 
    7854 #ifdef DEBUG_LOCAL2
    7855   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputW(%08x,%08x,x=%u y=%u,x=%u y=%u, %08x).\n",
    7856            pHMHandleData,
    7857            pchiSrcBuffer,
    7858            coordSrcBufferSize.X,
    7859            coordSrcBufferSize.Y,
    7860            coordSrcBufferCoord.X,
    7861            coordSrcBufferCoord.Y,
    7862            psrctDestRect);
    7863 #endif
    7864 
    7865 
    7866   /* verify psrctDestRect first */
    7867   psrctDestRect->Left  = max(psrctDestRect->Left,  0);
    7868   psrctDestRect->Top   = max(psrctDestRect->Top,   0);
    7869   psrctDestRect->Right = min(psrctDestRect->Right, pConsoleBuffer->coordBufferSize.X - 1);
    7870   psrctDestRect->Bottom= min(psrctDestRect->Bottom,pConsoleBuffer->coordBufferSize.Y - 1);
    7871 
    7872                                                      /* verify target buffer */
    7873   if ( (coordSrcBufferSize.X < coordSrcBufferCoord.X) ||
    7874        (coordSrcBufferSize.Y < coordSrcBufferCoord.Y) )
    7875   {
    7876     SetLastError(ERROR_INVALID_PARAMETER);        /* set detailed error info */
    7877     return (FALSE);                                            /* API failed */
    7878   }
    7879 
    7880   ulCX = coordSrcBufferSize.X - coordSrcBufferCoord.X;
    7881   ulCY = coordSrcBufferSize.Y - coordSrcBufferCoord.Y;
    7882 
    7883   ulCX = min(ulCX, (psrctDestRect->Right  - psrctDestRect->Left));
    7884   ulCY = min(ulCY, (psrctDestRect->Bottom - psrctDestRect->Top));
    7885 
    7886                                   /* final calculation of the copy rectangle */
    7887   psrctDestRect->Right  = psrctDestRect->Left + ulCX;
    7888   psrctDestRect->Bottom = psrctDestRect->Top  + ulCY;
    7889 
    7890 
    7891   for (ulY = 0,
    7892        ulWriteY = psrctDestRect->Top;
    7893 
    7894        ulY <= ulCY;
    7895 
    7896        ulY++,
    7897        ulWriteY++)
    7898   {
    7899     pchi = pchiSrcBuffer + sizeof(CHAR_INFO) * coordSrcBufferCoord.X
    7900                           + sizeof(CHAR_INFO) * (coordSrcBufferCoord.Y + ulY)
    7901                             * coordSrcBufferSize.X;
    7902 
    7903                                 /* calculate pointer to start of screen line */
    7904     pszTarget = pConsoleBuffer->ppszLine[ulWriteY] + psrctDestRect->Left;
    7905 
    7906     for (ulX = 0,
    7907          ulWriteX = psrctDestRect->Left;
    7908 
    7909          ulX <= ulCX;
    7910 
    7911          ulX++,
    7912          ulWriteX++,
    7913          pchi++)
    7914     {
    7915                                             /* write character and attribute */
    7916       *pszTarget++ = (UCHAR)pchi->Char.UnicodeChar;  /* @@@PH unicode->ascii */
    7917       *pszTarget++ = (UCHAR)pchi->Attributes;
    7918     }
    7919   }
    7920 
    7921                                           /* update screen if active console */
    7922   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    7923     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    7924 
    7925   return (TRUE);                                            /* OK, that's it */
    7926 }
    7927 
    7928 
    7929 /*****************************************************************************
    7930  * Name      : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputAttribute
    7931  * Purpose   : write an array with specified attributes to the console
    7932  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    7933  *             LPWORD        lpwAttribute
    7934  *             DWORD         cWriteCells
    7935  *             COORD         dwWriteCoord
    7936  *             LPDWORD       lpcWritten
    7937  * Variables :
    7938  * Result    :
    7939  * Remark    :
    7940  * Status    : UNTESTED
    7941  *
    7942  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    7943  *****************************************************************************/
    7944 
    7945 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputAttribute(PHMHANDLEDATA pHMHandleData,
    7946                                                               LPWORD        lpwAttribute,
    7947                                                               DWORD         cWriteCells,
    7948                                                               COORD         dwWriteCoord,
    7949                                                               LPDWORD       lpcWritten)
    7950 {
    7951   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    7952   ULONG          ulCounter;                     /* current character counter */
    7953 
    7954 #ifdef DEBUG_LOCAL2
    7955   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputAttribute(%08x,pattr=%08x,%u,x=%u y=%u,res=%08x).\n",
    7956            pHMHandleData,
    7957            lpwAttribute,
    7958 
    7959 
    7960            cWriteCells,
    7961            dwWriteCoord.X,
    7962            dwWriteCoord.Y,
    7963            lpcWritten);
    7964 #endif
    7965 
    7966   if ( (dwWriteCoord.X < 0) ||
    7967        (dwWriteCoord.Y < 0) )
    7968   {
    7969     if (lpcWritten != NULL)                       /* ensure pointer is valid */
    7970       *lpcWritten = 0;                            /* complete error handling */
    7971 
    7972     SetLastError(ERROR_INVALID_PARAMETER);
    7973     return (FALSE);
    7974   }
    7975 
    7976                                     /* check if dwWriteCoord is within specs */
    7977   if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
    7978        (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
    7979   {
    7980     if (lpcWritten != NULL)                       /* ensure pointer is valid */
    7981       *lpcWritten = 0;                            /* complete error handling */
    7982 
    7983     SetLastError(ERROR_INVALID_PARAMETER);
    7984     return (FALSE);
    7985   }
    7986 
    7987 
    7988                                         /* OK, now write the attribute lines */
    7989   for (ulCounter = 0;
    7990        ulCounter < cWriteCells;
    7991        ulCounter++,
    7992        lpwAttribute++)
    7993   {
    7994                                                 /* write attribute into cell */
    7995     *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
    7996                               (dwWriteCoord.X * 2 + 1)
    7997      ) = (UCHAR)*lpwAttribute;           /* write attribute and skip to next */
    7998 
    7999     dwWriteCoord.X++;                                 /* move write position */
    8000     if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
    8001     {
    8002       dwWriteCoord.X = 0;                               /* skip to next line */
    8003       dwWriteCoord.Y++;
    8004 
    8005                          /* oops, we're at the end of the buffer. Abort now. */
    8006       if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
    8007       {
    8008         if (lpcWritten != NULL)                   /* ensure pointer is valid */
    8009           *lpcWritten = ulCounter;
    8010 
    8011                                           /* update screen if active console */
    8012         if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    8013           ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */
    8014 
    8015         return (TRUE);
    8016       }
    8017     }
    8018   }
    8019 
    8020                                           /* update screen if active console */
    8021   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    8022     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    8023 
    8024   if (lpcWritten != NULL)                         /* ensure pointer is valid */
    8025     *lpcWritten = cWriteCells;
    8026 
    8027   return (TRUE);
    8028 }
    8029 
    8030 
    8031 /*****************************************************************************
    8032  * Name      : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterA
    8033  * Purpose   : fills the console buffer with a specified attribute
    8034  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    8035  *             LPTSTR        lpWriteBuffer
    8036  *             DWORD         cchWrite
    8037  *             COORD         dwWriteCoord
    8038  *             LPDWORD       lpcWritten
    8039  * Variables :
    8040  * Result    :
    8041  * Remark    :
    8042  * Status    : UNTESTED
    8043  *
    8044  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    8045  *****************************************************************************/
    8046 
    8047 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterA(PHMHANDLEDATA pHMHandleData,
    8048                                                                LPTSTR        lpWriteBuffer,
    8049                                                                DWORD         cchWrite,
    8050                                                                COORD         dwWriteCoord,
    8051                                                                LPDWORD       lpcWritten)
    8052 {
    8053   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    8054   ULONG          ulCounter;                     /* current character counter */
    8055 
    8056 #ifdef DEBUG_LOCAL2
    8057   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputCharacterA(%08x,pstr=%08x,%u,x=%u y=%u,res=%08x).\n",
    8058            pHMHandleData,
    8059            lpWriteBuffer,
    8060            cchWrite,
    8061            dwWriteCoord.X,
    8062            dwWriteCoord.Y,
    8063            lpcWritten);
    8064 #endif
    8065 
    8066   if ( (dwWriteCoord.X < 0) ||
    8067        (dwWriteCoord.Y < 0) )
    8068   {
    8069     if (lpcWritten != NULL)                       /* ensure pointer is valid */
    8070       *lpcWritten = 0;                            /* complete error handling */
    8071 
    8072     SetLastError(ERROR_INVALID_PARAMETER);
    8073     return (FALSE);
    8074   }
    8075 
    8076                                     /* check if dwWriteCoord is within specs */
    8077   if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
    8078        (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
    8079   {
    8080     if (lpcWritten != NULL)                       /* ensure pointer is valid */
    8081       *lpcWritten = 0;                            /* complete error handling */
    8082 
    8083     SetLastError(ERROR_INVALID_PARAMETER);
    8084     return (FALSE);
    8085   }
    8086 
    8087 
    8088                                         /* OK, now write the character lines */
    8089   for (ulCounter = 0;
    8090        ulCounter < cchWrite;
    8091        ulCounter++,
    8092        lpWriteBuffer++)
    8093   {
    8094                                                 /* write character into cell */
    8095     *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
    8096                               (dwWriteCoord.X * 2)
    8097      ) = (UCHAR)*lpWriteBuffer;          /* write character and skip to next */
    8098 
    8099     dwWriteCoord.X++;                                 /* move write position */
    8100     if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
    8101     {
    8102       dwWriteCoord.X = 0;                               /* skip to next line */
    8103       dwWriteCoord.Y++;
    8104 
    8105                          /* oops, we're at the end of the buffer. Abort now. */
    8106       if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
    8107       {
    8108         if (lpcWritten != NULL)                   /* ensure pointer is valid */
    8109           *lpcWritten = ulCounter;
    8110 
    8111                                           /* update screen if active console */
    8112         if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    8113           ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */
    8114 
    8115         return (TRUE);
    8116       }
    8117     }
    8118   }
    8119 
    8120                                           /* update screen if active console */
    8121   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    8122     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    8123 
    8124   if (lpcWritten != NULL)                         /* ensure pointer is valid */
    8125     *lpcWritten = cchWrite;
    8126 
    8127   return (TRUE);
    8128 }
    8129 
    8130 
    8131 /*****************************************************************************
    8132  * Name      : DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterW
    8133  * Purpose   : fills the console buffer with a specified attribute
    8134  * Parameters: PHMHANDLEDATA pHMHandleData - handle specific data
    8135  *             LPWSTR        lpWriteBuffer
    8136  *             DWORD         cchWrite
    8137  *             COORD         dwWriteCoord
    8138  *             LPDWORD       lpcWritten
    8139  * Variables :
    8140  * Result    :
    8141  * Remark    :
    8142  * Status    : UNTESTED
    8143  *
    8144  * Author    : Patrick Haller [Wed, 1998/02/16 11:46]
    8145  *****************************************************************************/
    8146 
    8147 DWORD HMDeviceConsoleBufferClass::WriteConsoleOutputCharacterW(PHMHANDLEDATA pHMHandleData,
    8148                                                                LPWSTR        lpWriteBuffer,
    8149                                                                DWORD         cchWrite,
    8150                                                                COORD         dwWriteCoord,
    8151                                                                LPDWORD       lpcWritten)
    8152 {
    8153   PCONSOLEBUFFER pConsoleBuffer = (PCONSOLEBUFFER)pHMHandleData->lpHandlerData;
    8154   ULONG          ulCounter;                     /* current character counter */
    8155 
    8156 #ifdef DEBUG_LOCAL2
    8157   WriteLog("KERNEL32/CONSOLE: CONBUFFER$::WriteConsoleOutputCharacterW(%08x,pstr=%08x,%u,x=%u y=%u,res=%08x).\n",
    8158            pHMHandleData,
    8159            lpWriteBuffer,
    8160            cchWrite,
    8161            dwWriteCoord.X,
    8162            dwWriteCoord.Y,
    8163            lpcWritten);
    8164 #endif
    8165 
    8166   if ( (dwWriteCoord.X < 0) ||
    8167        (dwWriteCoord.Y < 0) )
    8168   {
    8169     if (lpcWritten != NULL)                       /* ensure pointer is valid */
    8170       *lpcWritten = 0;                            /* complete error handling */
    8171 
    8172     SetLastError(ERROR_INVALID_PARAMETER);
    8173     return (FALSE);
    8174   }
    8175 
    8176                                     /* check if dwWriteCoord is within specs */
    8177   if ( (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X) ||
    8178        (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y) )
    8179   {
    8180     if (lpcWritten != NULL)                       /* ensure pointer is valid */
    8181       *lpcWritten = 0;                            /* complete error handling */
    8182 
    8183     SetLastError(ERROR_INVALID_PARAMETER);
    8184     return (FALSE);
    8185   }
    8186 
    8187 
    8188                                         /* OK, now write the character lines */
    8189   for (ulCounter = 0;
    8190        ulCounter < cchWrite;
    8191        ulCounter++,
    8192        lpWriteBuffer++)
    8193   {
    8194                                                 /* write character into cell */
    8195     *(pConsoleBuffer->ppszLine[dwWriteCoord.Y] +
    8196                               (dwWriteCoord.X * 2)
    8197      ) = (UCHAR)*lpWriteBuffer;          /* write character and skip to next */
    8198                                        /* @@@PH unicode to ascii translation */
    8199 
    8200     dwWriteCoord.X++;                                 /* move write position */
    8201     if (dwWriteCoord.X >= pConsoleBuffer->coordBufferSize.X)
    8202     {
    8203       dwWriteCoord.X = 0;                               /* skip to next line */
    8204       dwWriteCoord.Y++;
    8205 
    8206                          /* oops, we're at the end of the buffer. Abort now. */
    8207       if (dwWriteCoord.Y >= pConsoleBuffer->coordBufferSize.Y)
    8208       {
    8209         if (lpcWritten != NULL)                   /* ensure pointer is valid */
    8210           *lpcWritten = ulCounter;
    8211 
    8212                                           /* update screen if active console */
    8213         if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    8214           ConsoleGlobals.fUpdateRequired = TRUE;/* update with next WM_TIMER */
    8215 
    8216         return (TRUE);
    8217       }
    8218     }
    8219   }
    8220 
    8221                                           /* update screen if active console */
    8222   if (pHMHandleData->hHandle == ConsoleGlobals.hConsoleBuffer)
    8223     ConsoleGlobals.fUpdateRequired = TRUE;      /* update with next WM_TIMER */
    8224 
    8225   if (lpcWritten != NULL)                         /* ensure pointer is valid */
    8226     *lpcWritten = cchWrite;
    8227 
    8228   return (TRUE);
    8229 }
    8230 
Note: See TracChangeset for help on using the changeset viewer.