ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

hdlsterm.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         BSD - See COPYING.ARM in the top level directory
00004  * FILE:            ntoskrnl/ex/hdlsterm.c
00005  * PURPOSE:         Headless Terminal Support
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <ntoskrnl.h>
00012 #include <debug.h>
00013 
00014 /* GLOBALS *******************************************************************/
00015 
00016 PHEADLESS_GLOBALS HeadlessGlobals;
00017 
00018 /* FUNCTIONS *****************************************************************/
00019 
00020 VOID
00021 NTAPI
00022 HdlspSendStringAtBaud(
00023     IN PUCHAR String
00024     )
00025 {
00026     /* Send every byte */
00027     while (*String++ != ANSI_NULL)
00028     {
00029         InbvPortPutByte(HeadlessGlobals->TerminalPort, *String);
00030     }
00031 }
00032 
00033 NTSTATUS
00034 NTAPI
00035 HdlspEnableTerminal(
00036     IN BOOLEAN Enable
00037     )
00038 {
00039     /* Enable if requested, as long as this isn't a PCI serial port crashing */
00040     if ((Enable) &&
00041         !(HeadlessGlobals->TerminalEnabled) &&
00042         !((HeadlessGlobals->IsMMIODevice) && (HeadlessGlobals->InBugCheck)))
00043     {
00044         /* Initialize the COM port with cportlib */
00045         HeadlessGlobals->TerminalEnabled = InbvPortInitialize(
00046             HeadlessGlobals->TerminalBaudRate,
00047             HeadlessGlobals->TerminalPortNumber,
00048             HeadlessGlobals->TerminalPortAddress,
00049             &HeadlessGlobals->TerminalPort,
00050             HeadlessGlobals->IsMMIODevice);
00051         if (!HeadlessGlobals->TerminalEnabled) return STATUS_UNSUCCESSFUL;
00052 
00053         /* Cleanup the screen and reset the cursor */
00054         HdlspSendStringAtBaud((PUCHAR)"\x1B[2J");
00055         HdlspSendStringAtBaud((PUCHAR)"\x1B[H");
00056 
00057         /* Enable FIFO */
00058         InbvPortEnableFifo(HeadlessGlobals->TerminalPort, TRUE);
00059     }
00060     else if (!Enable)
00061     {
00062         /* Specific case when headless is being disabled */
00063         InbvPortTerminate(HeadlessGlobals->TerminalPort);
00064         HeadlessGlobals->TerminalPort = 0;
00065         HeadlessGlobals->TerminalEnabled = FALSE;
00066     }
00067     return STATUS_SUCCESS;
00068 }
00069 
00070 VOID
00071 NTAPI
00072 INIT_FUNCTION
00073 HeadlessInit(
00074     IN PLOADER_PARAMETER_BLOCK LoaderBlock
00075     )
00076 {
00077     PHEADLESS_LOADER_BLOCK HeadlessBlock;
00078 
00079     HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock;
00080     if (!HeadlessBlock) return;
00081     if ((HeadlessBlock->PortNumber > 4) && (HeadlessBlock->UsedBiosSettings)) return;
00082 
00083     HeadlessGlobals = ExAllocatePoolWithTag(
00084         NonPagedPool,
00085         sizeof(HEADLESS_GLOBALS),
00086         'sldH');
00087     if (!HeadlessGlobals) return;
00088 
00089     /* Zero and copy loader data */
00090     RtlZeroMemory(HeadlessGlobals, sizeof(HEADLESS_GLOBALS));
00091     HeadlessGlobals->TerminalPortNumber = HeadlessBlock->PortNumber;
00092     HeadlessGlobals->TerminalPortAddress = HeadlessBlock->PortAddress;
00093     HeadlessGlobals->TerminalBaudRate = HeadlessBlock->BaudRate;
00094     HeadlessGlobals->TerminalParity = HeadlessBlock->Parity;
00095     HeadlessGlobals->TerminalStopBits = HeadlessBlock->StopBits;
00096     HeadlessGlobals->UsedBiosSettings = HeadlessBlock->UsedBiosSettings;
00097     HeadlessGlobals->IsMMIODevice = HeadlessBlock->IsMMIODevice;
00098     HeadlessGlobals->TerminalType = HeadlessBlock->TerminalType;
00099     HeadlessGlobals->SystemGUID = HeadlessBlock->SystemGUID;
00100 
00101     /* These two are opposites of each other */
00102     if (HeadlessGlobals->IsMMIODevice) HeadlessGlobals->IsNonLegacyDevice = TRUE;
00103 
00104     /* Check for a PCI device, warn that this isn't supported */
00105     if (HeadlessBlock->PciDeviceId != PCI_INVALID_VENDORID)
00106     {
00107         DPRINT1("PCI Serial Ports not supported\n");
00108     }
00109 
00110     /* Log entries are not yet supported */
00111     DPRINT1("FIXME: No Headless logging support\n");
00112 
00113     /* Allocate temporary buffer */
00114     HeadlessGlobals->TmpBuffer = ExAllocatePoolWithTag(NonPagedPool, 80, 'sldH');
00115     if (!HeadlessGlobals->TmpBuffer) return;
00116 
00117     /* Windows seems to apply some special hacks for 9600 bps */
00118     if (HeadlessGlobals->TerminalBaudRate == 9600)
00119     {
00120         DPRINT1("Please use other baud rate than 9600bps for now\n");
00121     }
00122 
00123     /* Enable the terminal */
00124     HdlspEnableTerminal(TRUE);
00125 }
00126 
00127 VOID
00128 NTAPI
00129 HdlspPutString(
00130     IN PUCHAR String
00131     )
00132 {
00133     PUCHAR Dest = HeadlessGlobals->TmpBuffer;
00134     UCHAR Char = 0;
00135 
00136     /* Scan each character */
00137     while (*String != ANSI_NULL)
00138     {
00139         /* Check for rotate, send existing buffer and restart from where we are */
00140         if (Dest >= &HeadlessGlobals->TmpBuffer[79])
00141         {
00142             HeadlessGlobals->TmpBuffer[79] = ANSI_NULL;
00143             HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
00144             Dest = HeadlessGlobals->TmpBuffer;
00145         }
00146         else
00147         {
00148             /* Get the current character and check for special graphical chars */
00149             Char = *String;
00150             if (Char & 0x80)
00151             {
00152                 switch (Char)
00153                 {
00154                     case 0xB0: case 0xB3: case 0xBA:
00155                         Char = '|';
00156                         break;
00157                     case 0xB1: case 0xDC: case 0xDD: case 0xDE: case 0xDF:
00158                         Char = '%';
00159                         break;
00160                     case 0xB2: case 0xDB:
00161                         Char = '#';
00162                         break;
00163                     case 0xA9: case 0xAA: case 0xBB: case 0xBC: case 0xBF:
00164                     case 0xC0: case 0xC8: case 0xC9: case 0xD9: case 0xDA:
00165                         Char = '+';
00166                         break;
00167                     case 0xC4:
00168                         Char = '-';
00169                         break;
00170                     case 0xCD:
00171                         Char = '=';
00172                         break;
00173                     }
00174             }
00175 
00176             /* Anything else must be Unicode */
00177             if (Char & 0x80)
00178             {
00179                 /* Can't do Unicode yet */
00180                 UNIMPLEMENTED;
00181             }
00182             else
00183             {
00184                 /* Add the modified char to the temporary buffer */
00185                 *Dest++ = Char;
00186             }
00187             
00188             /* Check the next char */
00189             String++;
00190         }
00191     }
00192 
00193     /* Finish and send */
00194     *Dest = ANSI_NULL;
00195     HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
00196 }
00197 
00198 NTSTATUS
00199 NTAPI
00200 HdlspDispatch(
00201     IN HEADLESS_CMD Command,
00202     IN PVOID InputBuffer,
00203     IN SIZE_T InputBufferSize,
00204     OUT PVOID OutputBuffer,
00205     OUT PSIZE_T OutputBufferSize
00206     )
00207 {
00208     //NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
00209     ASSERT(HeadlessGlobals != NULL);
00210 //  ASSERT(HeadlessGlobals->PageLockHandle != NULL);
00211 
00212     /* FIXME: This should be using the headless spinlock */
00213 
00214     /* Ignore non-reentrant commands */
00215     if ((Command != HeadlessCmdAddLogEntry) &&
00216         (Command != HeadlessCmdStartBugCheck) &&
00217         (Command != HeadlessCmdSendBlueScreenData) &&
00218         (Command != HeadlessCmdDoBugCheckProcessing))
00219     {
00220         if (HeadlessGlobals->ProcessingCmd) return STATUS_UNSUCCESSFUL;
00221 
00222         /* Don't allow these commands next time */
00223         HeadlessGlobals->ProcessingCmd = TRUE;
00224     }
00225 
00226     /* Handle each command */
00227     switch (Command)
00228     {
00229         case HeadlessCmdEnableTerminal:
00230             break;
00231         case HeadlessCmdCheckForReboot:
00232             break;
00233 
00234         case HeadlessCmdPutString:
00235 
00236             /* Validate the existence of an input buffer */
00237             if (!InputBuffer)
00238             {
00239                 //Status = STATUS_INVALID_PARAMETER;
00240                 goto Reset;
00241             }
00242 
00243             /* Terminal should be on */
00244             if (HeadlessGlobals->TerminalEnabled)
00245             {
00246                 /* Print each byte in the string making sure VT100 chars are used */
00247                 PHEADLESS_CMD_PUT_STRING PutString = (PVOID)InputBuffer;
00248                 HdlspPutString(PutString->String);
00249             }
00250 
00251             /* Return success either way */
00252             //Status = STATUS_SUCCESS;
00253             break;
00254         case HeadlessCmdClearDisplay:
00255             break;
00256         case HeadlessCmdClearToEndOfDisplay:
00257             break;
00258         case HeadlessCmdClearToEndOfLine:
00259             break;
00260         case HeadlessCmdDisplayAttributesOff:
00261             break;
00262         case HeadlessCmdDisplayInverseVideo:
00263             break;
00264         case HeadlessCmdSetColor:
00265             break;
00266         case HeadlessCmdPositionCursor:
00267             break;
00268         case HeadlessCmdTerminalPoll:
00269             break;
00270         case HeadlessCmdGetByte:
00271             break;
00272         case HeadlessCmdGetLine:
00273             break;
00274         case HeadlessCmdStartBugCheck:
00275             break;
00276         case HeadlessCmdDoBugCheckProcessing:
00277             break;
00278         case HeadlessCmdQueryInformation:
00279             break;
00280         case HeadlessCmdAddLogEntry:
00281             break;
00282         case HeadlessCmdDisplayLog:
00283             break;
00284         case HeadlessCmdSetBlueScreenData:
00285             break;
00286         case HeadlessCmdSendBlueScreenData:
00287             break;
00288         case HeadlessCmdQueryGUID:
00289             break;
00290         case HeadlessCmdPutData:
00291             break;
00292         default:
00293             break;
00294     }
00295 
00296 Reset:
00297     /* Unset prcessing state */
00298     if ((Command != HeadlessCmdAddLogEntry) &&
00299         (Command != HeadlessCmdStartBugCheck) &&
00300         (Command != HeadlessCmdSendBlueScreenData) &&
00301         (Command != HeadlessCmdDoBugCheckProcessing))
00302     {
00303         ASSERT(HeadlessGlobals->ProcessingCmd == TRUE);
00304         HeadlessGlobals->ProcessingCmd = FALSE;
00305     }
00306 
00307     //UNIMPLEMENTED;
00308     return STATUS_SUCCESS;
00309 }
00310 
00311 /*
00312  * @unimplemented
00313  */
00314 NTSTATUS
00315 NTAPI
00316 HeadlessDispatch(
00317     IN HEADLESS_CMD Command,
00318     IN PVOID InputBuffer,
00319     IN SIZE_T InputBufferSize,
00320     OUT PVOID OutputBuffer,
00321     OUT PSIZE_T OutputBufferSize
00322     )
00323 {
00324     /* Check for stubs that will expect something even with headless off */
00325     if (!HeadlessGlobals)
00326     {
00327         /* Don't allow the SAC to connect */
00328         if (Command == HeadlessCmdEnableTerminal) return STATUS_UNSUCCESSFUL;
00329 
00330         /* Send bogus reply */
00331         if ((Command == HeadlessCmdQueryInformation) ||
00332             (Command == HeadlessCmdGetByte) ||
00333             (Command == HeadlessCmdGetLine) ||
00334             (Command == HeadlessCmdCheckForReboot) ||
00335             (Command == HeadlessCmdTerminalPoll))
00336         {
00337             if (!(OutputBuffer) || !(OutputBufferSize)) return STATUS_INVALID_PARAMETER;
00338             RtlZeroMemory(OutputBuffer, *OutputBufferSize);
00339         }
00340         return STATUS_SUCCESS;
00341     }
00342     
00343     /* Do the real work */
00344     return HdlspDispatch(
00345         Command, 
00346         InputBuffer,
00347         InputBufferSize,
00348         OutputBuffer,
00349         OutputBufferSize);
00350 }    
00351 
00352 /* EOF */

Generated on Sat May 26 2012 04:36:03 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.