Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhdlsterm.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
1.7.6.1
|