doswin.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:10k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * doswin.cxx
  3.  *
  4.  * 16 bit implementation for MS-DOS and 16 bit Windows.
  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.  * $Log: doswin.cxx,v $
  30.  * Revision 1.10  1998/09/24 03:30:43  robertj
  31.  * Added open software license.
  32.  *
  33.  * Revision 1.9  1996/01/02 12:55:15  robertj
  34.  * Fixed copy of directories.
  35.  *
  36.  * Revision 1.8  1995/12/10 11:56:42  robertj
  37.  * Moved error code for specific WIN32 and MS-DOS versions.
  38.  *
  39.  * Revision 1.7  1995/08/24 12:41:10  robertj
  40.  * Changed PChannel so not a PContainer.
  41.  *
  42.  * Revision 1.6  1995/07/31 12:14:52  robertj
  43.  * Added semaphore class.
  44.  *
  45.  * Revision 1.5  1995/06/17 00:59:18  robertj
  46.  * Moved PPipeChannel::Execute from common dos/windows to individual files.
  47.  *
  48.  * Revision 1.4  1995/04/01 08:05:59  robertj
  49.  * Fixed yield for straight DOS and QUICKWIN systems.
  50.  *
  51.  * Revision 1.3  1995/03/25 02:09:11  robertj
  52.  * Added check for network login name.
  53.  *
  54. // Revision 1.2  1995/03/14  13:31:36  robertj
  55. // Implemented DOS pipe channel.
  56. //
  57. // Revision 1.1  1995/03/14  12:45:16  robertj
  58. // Initial revision
  59. //
  60.  */
  61. #include "ptlib.h"
  62. #include <fcntl.h>
  63. #include <sys/stat.h>
  64. ///////////////////////////////////////////////////////////////////////////////
  65. // Directories
  66. void PDirectory::Construct()
  67. {
  68.   PString::operator=(CreateFullPath(*this, TRUE));
  69. }
  70. void PDirectory::CopyContents(const PDirectory & dir)
  71. {
  72.   scanMask = dir.scanMask;
  73.   fileinfo = dir.fileinfo;
  74. }
  75. BOOL PDirectory::Open(int newScanMask)
  76. {
  77.   scanMask = newScanMask;
  78.   if (_dos_findfirst(*this+"*.*", 0xff, &fileinfo) != 0)
  79.     return FALSE;
  80.   return Filtered() ? Next() : TRUE;
  81. }
  82. BOOL PDirectory::Next()
  83. {
  84.   do {
  85.     if (_dos_findnext(&fileinfo) != 0)
  86.       return FALSE;
  87.   } while (Filtered());
  88.   return TRUE;
  89. }
  90. PCaselessString PDirectory::GetEntryName() const
  91. {
  92.   return fileinfo.name;
  93. }
  94. BOOL PDirectory::IsSubDir() const
  95. {
  96.   return (fileinfo.attrib&_A_SUBDIR) != 0;
  97. }
  98. void PDirectory::Close()
  99. {
  100.   /* do nothing */
  101. }
  102. PCaselessString PDirectory::GetVolume() const
  103. {
  104.   struct find_t finf;
  105.   if (_dos_findfirst(Left(3) + "*.*", _A_VOLID, &finf) != 0)
  106.     return PCaselessString();
  107.   return finf.name;
  108. }
  109. PString PDirectory::CreateFullPath(const PString & path, BOOL isDirectory)
  110. {
  111.   PString curdir;
  112.   PAssert(getcwd(curdir.GetPointer(P_MAX_PATH),
  113.                                    P_MAX_PATH) != NULL, POperatingSystemError);
  114.   PString fullpath;
  115.   PINDEX offset;
  116.   if (path.GetLength() < 2 || path[1] != ':') {
  117.     fullpath = curdir(0,1);
  118.     offset = 0;
  119.   }
  120.   else {
  121.     fullpath = path(0,1).ToUpper();
  122.     offset = 2;
  123.   }
  124.   char slash = path[offset];
  125.   if (slash != '\' && slash != '/') {
  126.     if (fullpath[0] == curdir[0])
  127.       fullpath += curdir(2, P_MAX_INDEX);
  128.     else if (_chdrive(fullpath[0]-'A'+1) == 0) {
  129.       PString otherdir;
  130.       PAssert(getcwd(otherdir.GetPointer(P_MAX_PATH),
  131.                                    P_MAX_PATH) != NULL, POperatingSystemError);
  132.       fullpath += otherdir(2, P_MAX_INDEX);
  133.       _chdrive(curdir[0]-'A'+1);  // Put drive back
  134.     }
  135.     slash = fullpath[fullpath.GetLength()-1];
  136.     if (slash != '\' && slash != '/')
  137.       fullpath += "\";
  138.   }
  139.   fullpath += path(offset, P_MAX_INDEX);
  140.   slash = fullpath[fullpath.GetLength()-1];
  141.   if (isDirectory && slash != '\' && slash != '/')
  142.     fullpath += "\";
  143.   int pos;
  144.   while ((pos = fullpath.Find('/')) != P_MAX_INDEX)
  145.     fullpath[pos] = '\';
  146.   while ((pos = fullpath.Find("\.\")) != P_MAX_INDEX)
  147.     fullpath = fullpath(0, pos) + fullpath(pos+3, P_MAX_INDEX);
  148.   while ((pos = fullpath.Find("\..\")) != P_MAX_INDEX)
  149.     fullpath = fullpath(0, fullpath.FindLast('\', pos-1)) +
  150.                                                   fullpath(pos+4, P_MAX_INDEX);
  151.   return fullpath.ToUpper();
  152. }
  153. ///////////////////////////////////////////////////////////////////////////////
  154. // PChannel
  155. PString PChannel::GetErrorText() const
  156. {
  157.   if (osError == 0)
  158.     return PString();
  159.   if (osError > 0 && osError < _sys_nerr && _sys_errlist[osError][0] != '')
  160.     return _sys_errlist[osError];
  161.   return psprintf("OS error %u", osError);
  162. }
  163. BOOL PChannel::ConvertOSError(int error)
  164. {
  165.   if (error >= 0) {
  166.     lastError = NoError;
  167.     osError = 0;
  168.     return TRUE;
  169.   }
  170.   osError = errno;
  171.   switch (osError) {
  172.     case 0 :
  173.       lastError = NoError;
  174.       return TRUE;
  175.     case ENOENT :
  176.       lastError = NotFound;
  177.       break;
  178.     case EEXIST :
  179.       lastError = FileExists;
  180.       break;
  181.     case EACCES :
  182.       lastError = AccessDenied;
  183.       break;
  184.     case ENOMEM :
  185.       lastError = NoMemory;
  186.       break;
  187.     case ENOSPC :
  188.       lastError = DiskFull;
  189.       break;
  190.     case EINVAL :
  191.       lastError = BadParameter;
  192.       break;
  193.     case EBADF :
  194.       lastError = NotOpen;
  195.       break;
  196.     default :
  197.       lastError = Miscellaneous;
  198.   }
  199.   return FALSE;
  200. }
  201. ///////////////////////////////////////////////////////////////////////////////
  202. // PPipeChannel
  203. void PPipeChannel::Construct(const PString & subProgram,
  204.                 const char * const * arguments, OpenMode mode, BOOL searchPath)
  205. {
  206.   hasRun = FALSE;
  207.   if (searchPath || subProgram.FindOneOf(":\/") != P_MAX_INDEX)
  208.     subProgName = subProgram;
  209.   else
  210.     subProgName = ".\" + subProgram;
  211.   if (arguments != NULL) {
  212.     while (*arguments != NULL) {
  213.       subProgName += " ";
  214.       if (strchr(*arguments, ' ') == NULL)
  215.         subProgName += *arguments;
  216.       else {
  217.         PString quote = '"';
  218.         subProgName += quote + *arguments + quote;
  219.       }
  220.     }
  221.   }
  222.   
  223.   if (mode != ReadOnly) {
  224.     toChild = PFilePath("pw", NULL);
  225.     os_handle = _open(toChild, _O_WRONLY|_O_CREAT|_O_BINARY,S_IREAD|S_IWRITE);
  226.     if (!ConvertOSError(os_handle))
  227.       return;
  228.     subProgName += '<' + toChild;
  229.   }
  230.   if (mode != WriteOnly) {
  231.     fromChild = PFilePath("pw", NULL);
  232.     subProgName += '>' + fromChild;
  233.   }
  234.   if (mode == ReadOnly)
  235.     Execute();
  236. }
  237. PPipeChannel::~PPipeChannel()
  238. {
  239.   Close();
  240. }
  241. BOOL PPipeChannel::Read(void * buffer, PINDEX amount)
  242. {
  243.   if (!hasRun)
  244.     Execute();
  245.   flush();
  246.   lastReadCount = _read(GetHandle(), buffer, amount);
  247.   return ConvertOSError(lastReadCount) && lastReadCount > 0;
  248. }
  249.       
  250. BOOL PPipeChannel::Write(const void * buffer, PINDEX amount)
  251. {
  252.   if (hasRun) {
  253.     osError = EBADF;
  254.     lastError = NotOpen;
  255.     return FALSE;
  256.   }
  257.   flush();
  258.   lastWriteCount = _write(GetHandle(), buffer, amount);
  259.   return ConvertOSError(lastWriteCount) && lastWriteCount >= amount;
  260. }
  261. BOOL PPipeChannel::Close()
  262. {
  263.   if (!hasRun)
  264.     Execute();
  265.   if (os_handle >= 0)
  266.     _close(os_handle);
  267.   PFile::Remove(toChild);
  268.   PFile::Remove(fromChild);
  269.   return TRUE;
  270. }
  271. ///////////////////////////////////////////////////////////////////////////////
  272. // PThread
  273. PThread::~PThread()
  274. {
  275.   Terminate();
  276.   _nfree(stackBase);   // Give stack back to the near heap
  277. }
  278. void PThread::Block(BlockFunction isBlockFun, PObject * obj)
  279. {
  280.   isBlocked = isBlockFun;
  281.   blocker = obj;
  282.   status = BlockedIO;
  283.   Yield();
  284. }
  285. ///////////////////////////////////////////////////////////////////////////////
  286. // PProcess
  287. void PProcess::OperatingSystemYield()
  288. {
  289. #ifdef P_QUICKWIN
  290.   _wyield();
  291. #endif
  292. }
  293. PString PProcess::GetUserName() const
  294. {
  295.   /* ----- Microsoft LAN Manager, Windows for Workgroups, IBM LAN Server ----- */
  296. #pragma pack(1)
  297.   static struct {
  298.     char _far *computername;
  299.     char _far *username;
  300.     char _far *langroup;
  301.     unsigned char ver_major;
  302.     unsigned char ver_minor;
  303.     char _far *logon_domain;
  304.     char _far *oth_domains;
  305.     char filler[32];
  306.   } NEAR wksta;
  307. #pragma pack()
  308.   union REGS r;
  309.   r.x.ax = 0x5F44;
  310.   r.x.bx = 10;
  311.   r.x.cx = sizeof(wksta);
  312.   r.x.di = (WORD)&wksta;
  313.   struct SREGS sregs;
  314.   segread(&sregs);
  315.   sregs.es = sregs.ds;
  316.   int86x(0x21, &r, &r, &sregs);
  317.   if (r.x.ax == 0 || r.x.ax == 0x5F44) {
  318.     char name[32];
  319.     strcpy(name, wksta.username);
  320.     strlwr(name);
  321.     return name;
  322.   }
  323.   /* ----- Novell NetWare ----- Get Connection Information E3(16) */
  324. #pragma pack(1)
  325.   static struct {
  326.     unsigned short len;
  327.     unsigned char func;
  328.     unsigned char number;
  329.   } NEAR gcireq;
  330.   
  331.   static struct {
  332.     unsigned short len;
  333.     unsigned long objectID;
  334.     unsigned short objecttype;
  335.     char objectname[48];
  336.     unsigned char logintime[7];
  337.     unsigned char reserved[39];
  338.   } NEAR gcirep;
  339. #pragma pack()
  340.   /* Load Get Connection Number function code.   */
  341.   r.x.ax = 0xDC00;
  342.   int86x(0x21, &r, &r, &sregs);
  343.   if (r.h.al > 0 && r.h.al <= 100) {
  344.     /* If the connection number is in range 1-100,
  345.      * invoke Get Connection Information to get the user name. */
  346.     gcireq.len = sizeof(gcireq) - sizeof(gcireq.len);
  347.     gcireq.func = 0x16;
  348.     gcireq.number = r.h.al;
  349.     gcirep.len = sizeof(gcirep) - sizeof(gcirep.len);
  350.     r.h.ah = 0xE3;
  351.     r.x.si = (unsigned short) &gcireq;
  352.     r.x.di = (unsigned short) &gcirep;
  353.     int86x(0x21, &r, &r, &sregs);
  354.     if (r.h.al == 0) {
  355.       strlwr(gcirep.objectname);
  356.       return gcirep.objectname;
  357.     }
  358.   }
  359.   /* Give up and use environment variables */
  360.   const char * username = getenv("LOGNAME");
  361.   if (username == NULL) {
  362.     username = getenv("USER");
  363.     if (username == NULL)
  364.       username = "";
  365.   }
  366.   
  367.   PAssert(*username != '', "Cannot determine user name, set LOGNAME.");
  368.   return username;
  369. }
  370. // End Of File ///////////////////////////////////////////////////////////////