1 /*
2  * msdos.cxx
3  *
4  * General class implementation for MS-DOS
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 20385 $
30  * $Author: rjongbloed $
31  * $Date: 2008-06-04 05:40:38 -0500 (Wed, 04 Jun 2008) $
32  */
33 
34 #include "ptlib.h"
35 
36 #include <bios.h>
37 #include <fcntl.h>
38 
39 
40 ///////////////////////////////////////////////////////////////////////////////
41 // PTime
42 
GetTimeSeparator()43 PString PTime::GetTimeSeparator()
44 {
45   return "";
46 }
47 
48 
GetTimeAMPM()49 PBoolean PTime::GetTimeAMPM()
50 {
51   return PFalse;
52 }
53 
54 
GetTimeAM()55 PString PTime::GetTimeAM()
56 {
57   return "am";
58 }
59 
60 
GetTimePM()61 PString PTime::GetTimePM()
62 {
63   return "pm";
64 }
65 
66 
GetDayName(Weekdays dayOfWeek,NameType type)67 PString PTime::GetDayName(Weekdays dayOfWeek, NameType type)
68 {
69   static const char * const weekdays[] = {
70     "Sunday", "Monday", "Tuesday", "Wednesday",
71     "Thursday", "Friday", "Saturday"
72   };
73   static const char * const abbrev_weekdays[] = {
74     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
75   };
76   return (type != FullName ? abbrev_weekdays : weekdays)[dayOfWeek];
77 }
78 
79 
GetDateSeparator()80 PString PTime::GetDateSeparator()
81 {
82   return "-";
83 }
84 
85 
GetMonthName(Months month,NameType type)86 PString PTime::GetMonthName(Months month, NameType type)
87 {
88   static const char * const months[] = { "",
89     "January", "February", "March", "April", "May", "June",
90     "July", "August", "September", "October", "November", "December"
91   };
92   static const char * const abbrev_months[] = {
93     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
94     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
95   };
96   return (type != FullName ? abbrev_months : months)[month];
97 }
98 
99 
GetDateOrder()100 PTime::DateOrder PTime::GetDateOrder()
101 {
102   return DayMonthYear;
103 }
104 
105 
GetTimeZone() const106 long PTime::GetTimeZone() const
107 {
108   return 0;
109 }
110 
111 
GetTimeZoneString(TimeZoneType type) const112 PString PTime::GetTimeZoneString(TimeZoneType type) const
113 {
114   return "";
115 }
116 
117 
118 
119 ///////////////////////////////////////////////////////////////////////////////
120 // PSerialChannel
121 
Construct()122 void PSerialChannel::Construct()
123 {
124   biosParm = 0xe3; // 9600 baud, no parity, 1 stop bit, 8 data bits
125 }
126 
127 
GetName() const128 PString PSerialChannel::GetName() const
129 {
130   if (IsOpen())
131     return psprintf("COM%i", os_handle+1);
132 
133   return PString();
134 }
135 
136 
Read(void * buf,PINDEX len)137 PBoolean PSerialChannel::Read(void * buf, PINDEX len)
138 {
139   char * b = (char *)buf;
140   while (len > 0) {
141     int c = ReadChar();
142     if (c >= 0) {
143       *b++ = (char)c;
144       len--;
145     }
146   }
147   return len == 0;
148 }
149 
150 
Write(const void * buf,PINDEX len)151 PBoolean PSerialChannel::Write(const void * buf, PINDEX len)
152 {
153   const char * b = (const char *)buf;
154   while (len-- > 0) {
155     if (!WriteChar(*b++))
156       return PFalse;
157   }
158   return PTrue;
159 }
160 
161 
Close()162 PBoolean PSerialChannel::Close()
163 {
164   if (!IsOpen())
165     return PFalse;
166 
167   os_handle = -1;
168   return PTrue;
169 }
170 
171 
SetCommsParam(DWORD speed,BYTE data,Parity parity,BYTE stop,FlowControl inputFlow,FlowControl outputFlow)172 PBoolean PSerialChannel::SetCommsParam(DWORD speed, BYTE data, Parity parity,
173                      BYTE stop, FlowControl inputFlow, FlowControl outputFlow)
174 {
175   switch (speed) {
176     case 0 :
177       break;
178     case 110 :
179       biosParm &= 0x1f;
180       break;
181     case 150 :
182       biosParm &= 0x1f;
183       biosParm |= 0x20;
184       break;
185     case 300 :
186       biosParm &= 0x1f;
187       biosParm |= 0x40;
188       break;
189     case 600 :
190       biosParm &= 0x1f;
191       biosParm |= 0x60;
192       break;
193     case 1200 :
194       biosParm &= 0x1f;
195       biosParm |= 0x80;
196       break;
197     case 2400 :
198       biosParm &= 0x1f;
199       biosParm |= 0xa0;
200       break;
201     case 4800 :
202       biosParm &= 0x1f;
203       biosParm |= 0xc0;
204       break;
205     case 9600 :
206       biosParm &= 0x1f;
207       biosParm |= 0xe0;
208       break;
209     default :
210       return PFalse;
211   }
212 
213   switch (data) {
214     case 0 :
215       break;
216     case 5 :
217       biosParm &= 0xfc;
218       break;
219     case 6 :
220       biosParm &= 0xfc;
221       biosParm |= 1;
222       break;
223     case 7 :
224       biosParm &= 0xfc;
225       biosParm |= 2;
226       break;
227     case 8 :
228       biosParm &= 0xfc;
229       biosParm |= 3;
230       break;
231     default :
232       return PFalse;
233   }
234 
235   switch (parity) {
236     case DefaultParity :
237       break;
238     case NoParity :
239       biosParm &= 0xe7;
240       break;
241     case OddParity :
242       biosParm &= 0xe7;
243       biosParm |= 8;
244       break;
245     case EvenParity :
246       biosParm &= 0xe7;
247       biosParm |= 0x10;
248       break;
249     default :
250       return PFalse;
251   }
252 
253   switch (stop) {
254     case 0 :
255       break;
256     case 1 :
257       biosParm &= ~4;
258       break;
259     case 2 :
260       biosParm |= 4;
261       break;
262     default :
263       return PFalse;
264   }
265 
266   if (outputFlow != DefaultFlowControl || inputFlow != DefaultFlowControl)
267     return PFalse;
268 
269   _bios_serialcom(_COM_INIT, os_handle, biosParm);
270   return PTrue;
271 }
272 
Open(const PString & port,DWORD speed,BYTE data,Parity parity,BYTE stop,FlowControl inputFlow,FlowControl outputFlow)273 PBoolean PSerialChannel::Open(const PString & port, DWORD speed, BYTE data,
274        Parity parity, BYTE stop, FlowControl inputFlow, FlowControl outputFlow)
275 {
276   Close();
277 
278   os_handle = -1;
279   if (PCaselessString("COM") != port.Left(3) &&
280                                               port[3] >= '1' && port[3] <= '4')
281     return PFalse;
282   os_handle = port[3] - '1';
283   return SetCommsParam(speed, data, parity, stop, inputFlow, outputFlow);
284 }
285 
286 
SetSpeed(DWORD speed)287 PBoolean PSerialChannel::SetSpeed(DWORD speed)
288 {
289   return SetCommsParam(speed,
290                  0, DefaultParity, 0, DefaultFlowControl, DefaultFlowControl);
291 }
292 
293 
GetSpeed() const294 DWORD PSerialChannel::GetSpeed() const
295 {
296   static int speed[8] = { 110, 150, 300, 600, 1200, 2400, 4800, 9600 };
297   return speed[biosParm>>5];
298 }
299 
300 
SetDataBits(BYTE data)301 PBoolean PSerialChannel::SetDataBits(BYTE data)
302 {
303   return SetCommsParam(0,
304               data, DefaultParity, 0, DefaultFlowControl, DefaultFlowControl);
305 }
306 
307 
GetDataBits() const308 BYTE PSerialChannel::GetDataBits() const
309 {
310   return (BYTE)((biosParm&3)+5);
311 }
312 
313 
SetParity(Parity parity)314 PBoolean PSerialChannel::SetParity(Parity parity)
315 {
316   return SetCommsParam(0,0, parity, 0, DefaultFlowControl, DefaultFlowControl);
317 }
318 
319 
GetParity() const320 PSerialChannel::Parity PSerialChannel::GetParity() const
321 {
322   return (biosParm&8) == 0 ? NoParity :
323                                 (biosParm&0x10) == 0 ? OddParity : EvenParity;
324 }
325 
326 
SetStopBits(BYTE stop)327 PBoolean PSerialChannel::SetStopBits(BYTE stop)
328 {
329   return SetCommsParam(0,
330                0, DefaultParity, stop, DefaultFlowControl, DefaultFlowControl);
331 }
332 
333 
GetStopBits() const334 BYTE PSerialChannel::GetStopBits() const
335 {
336   return (BYTE)(((biosParm&4)>>3)+1);
337 }
338 
339 
SetInputFlowControl(FlowControl flowControl)340 PBoolean PSerialChannel::SetInputFlowControl(FlowControl flowControl)
341 {
342   return SetCommsParam(0,0, DefaultParity, 0, flowControl, DefaultFlowControl);
343 }
344 
345 
GetInputFlowControl() const346 PSerialChannel::FlowControl PSerialChannel::GetInputFlowControl() const
347 {
348   return RtsCts;
349 }
350 
351 
SetOutputFlowControl(FlowControl flowControl)352 PBoolean PSerialChannel::SetOutputFlowControl(FlowControl flowControl)
353 {
354   return SetCommsParam(0,0, DefaultParity, 0, DefaultFlowControl, flowControl);
355 }
356 
357 
GetOutputFlowControl() const358 PSerialChannel::FlowControl PSerialChannel::GetOutputFlowControl() const
359 {
360   return RtsCts;
361 }
362 
363 
SetDTR(PBoolean state)364 void PSerialChannel::SetDTR(PBoolean state)
365 {
366   if (!IsOpen())
367     return;
368 
369 }
370 
371 
SetRTS(PBoolean state)372 void PSerialChannel::SetRTS(PBoolean state)
373 {
374   if (!IsOpen())
375     return;
376 
377 }
378 
379 
SetBreak(PBoolean state)380 void PSerialChannel::SetBreak(PBoolean state)
381 {
382   if (!IsOpen())
383     return;
384 
385   int s = state;
386 }
387 
388 
GetCTS()389 PBoolean PSerialChannel::GetCTS()
390 {
391   if (!IsOpen())
392     return PFalse;
393 
394   return (_bios_serialcom(_COM_STATUS, os_handle, 0)&0x8010) == 0x10;
395 }
396 
397 
GetDSR()398 PBoolean PSerialChannel::GetDSR()
399 {
400   if (!IsOpen())
401     return PFalse;
402 
403   return (_bios_serialcom(_COM_STATUS, os_handle, 0)&0x8020) == 0x20;
404 }
405 
406 
GetDCD()407 PBoolean PSerialChannel::GetDCD()
408 {
409   if (!IsOpen())
410     return PFalse;
411 
412   return (_bios_serialcom(_COM_STATUS, os_handle, 0)&0x8080) == 0x80;
413 }
414 
415 
GetRing()416 PBoolean PSerialChannel::GetRing()
417 {
418   if (!IsOpen())
419     return PFalse;
420 
421   return (_bios_serialcom(_COM_STATUS, os_handle, 0)&0x8040) == 0x40;
422 }
423 
424 
GetPortNames()425 PStringList PSerialChannel::GetPortNames()
426 {
427   static char buf[] = "COM ";
428   PStringList ports;
429   for (char p = '1'; p <= '4'; p++) {
430     if (*(WORD *)(0x00400000+p-'1') != 0) {
431       buf[3] = p;
432       ports.Append(new PString(buf));
433     }
434   }
435   return ports;
436 }
437 
438 
439 ///////////////////////////////////////////////////////////////////////////////
440 // PPipeChannel
441 
Execute()442 PBoolean PPipeChannel::Execute()
443 {
444   if (hasRun)
445     return PFalse;
446 
447   flush();
448   if (os_handle >= 0) {
449     _close(os_handle);
450     os_handle = -1;
451   }
452 
453   if (!ConvertOSError(system(subProgName)))
454     return PFalse;
455 
456   if (!fromChild.IsEmpty()) {
457     os_handle = _open(fromChild, _O_RDONLY);
458     if (!ConvertOSError(os_handle))
459       return PFalse;
460   }
461 
462   return PTrue;
463 }
464 
465 
466 ///////////////////////////////////////////////////////////////////////////////
467 // Configuration files
468 
Construct(Source src)469 void PConfig::Construct(Source src)
470 {
471   switch (src) {
472     case Application :
473       PFilePath appFile = PProcess::Current()->GetFile();
474       location = appFile.GetVolume() +
475                               appFile.GetPath() + appFile.GetTitle() + ".INI";
476   }
477 }
478 
479 
Construct(const PFilePath & file)480 void PConfig::Construct(const PFilePath & file)
481 {
482   location = file;
483 }
484 
485 
GetSections()486 PStringList PConfig::GetSections()
487 {
488   PStringList sections;
489 
490   if (!location.IsEmpty()) {
491     PAssertAlways(PUnimplementedFunction);
492   }
493 
494   return sections;
495 }
496 
497 
GetKeys(const PString &) const498 PStringList PConfig::GetKeys(const PString &) const
499 {
500   PStringList keys;
501 
502   if (location.IsEmpty()) {
503     char ** ptr = _environ;
504     while (*ptr != NULL) {
505       PString buf = *ptr++;
506       keys.AppendString(buf.Left(buf.Find('=')));
507     }
508   }
509   else {
510     PAssertAlways(PUnimplementedFunction);
511   }
512 
513   return keys;
514 }
515 
516 
DeleteSection(const PString &)517 void PConfig::DeleteSection(const PString &)
518 {
519   if (location.IsEmpty())
520     return;
521 
522   PAssertAlways(PUnimplementedFunction);
523 }
524 
525 
DeleteKey(const PString &,const PString & key)526 void PConfig::DeleteKey(const PString &, const PString & key)
527 {
528   if (location.IsEmpty()) {
529     PAssert(key.Find('=') == P_MAX_INDEX, PInvalidParameter);
530     _putenv(key + "=");
531   }
532   else
533     PAssertAlways(PUnimplementedFunction);
534 }
535 
536 
GetString(const PString &,const PString & key,const PString & dflt)537 PString PConfig::GetString(const PString &,
538                                           const PString & key, const PString & dflt)
539 {
540   PString str;
541 
542   if (location.IsEmpty()) {
543     PAssert(key.Find('=') == P_MAX_INDEX, PInvalidParameter);
544     char * env = getenv(key);
545     if (env != NULL)
546       str = env;
547     else
548       str = dflt;
549   }
550   else {
551     PAssertAlways(PUnimplementedFunction);
552   }
553   return str;
554 }
555 
556 
SetString(const PString &,const PString & key,const PString & value)557 void PConfig::SetString(const PString &, const PString & key, const PString & value)
558 {
559   if (location.IsEmpty()) {
560     PAssert(key.Find('=') == P_MAX_INDEX, PInvalidParameter);
561     _putenv(key + "=" + value);
562   }
563   else
564     PAssertAlways(PUnimplementedFunction);
565 }
566 
567 
568 
569 ///////////////////////////////////////////////////////////////////////////////
570 // Threads
571 
SwitchContext(PThread * from)572 void PThread::SwitchContext(PThread * from)
573 {
574   if (setjmp(from->context) != 0) // Are being reactivated from previous yield
575     return;
576 
577   if (status == Starting) {
578     if (setjmp(context) != 0) {
579       status = Running;
580       Main();
581       Terminate(); // Never returns from here
582     }
583     context[7] = (int)stackTop-16;  // Change the stack pointer in jmp_buf
584   }
585 
586   longjmp(context, PTrue);
587   PAssertAlways("longjmp failed"); // Should never get here
588 }
589 
590 
591 
592 ///////////////////////////////////////////////////////////////////////////////
593 // PDynaLink
594 
PDynaLink()595 PDynaLink::PDynaLink()
596 {
597   PAssertAlways(PUnimplementedFunction);
598 }
599 
600 
PDynaLink(const PString &)601 PDynaLink::PDynaLink(const PString &)
602 {
603   PAssertAlways(PUnimplementedFunction);
604 }
605 
606 
~PDynaLink()607 PDynaLink::~PDynaLink()
608 {
609 }
610 
611 
Open(const PString & name)612 PBoolean PDynaLink::Open(const PString & name)
613 {
614   PAssertAlways(PUnimplementedFunction);
615   return PFalse;
616 }
617 
618 
Close()619 void PDynaLink::Close()
620 {
621 }
622 
623 
IsLoaded() const624 PBoolean PDynaLink::IsLoaded() const
625 {
626   return PFalse;
627 }
628 
629 
GetFunction(PINDEX index,Function & func)630 PBoolean PDynaLink::GetFunction(PINDEX index, Function & func)
631 {
632   return PFalse;
633 }
634 
635 
GetFunction(const PString & name,Function & func)636 PBoolean PDynaLink::GetFunction(const PString & name, Function & func)
637 {
638   return PFalse;
639 }
640 
641 
642 
643 // End Of File ///////////////////////////////////////////////////////////////
644