home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / blt2_214.zip / src / ccdosfn.c < prev    next >
C/C++ Source or Header  |  1996-11-06  |  34KB  |  1,105 lines

  1.  
  2. /*
  3.  *
  4.  * Bullet 2 OS support routines
  5.  * ccdosfn.c - Copyright (C)1996 Cornel Huth
  6.  * 12-Oct-1996 -chh
  7.  *
  8.  * Note: if you are using any routine from the C standard library you
  9.  * most likely will need to use beginthread() to spawn Bullet
  10.  * threads (for example, a reindex thread as in bd_rix.c) instead
  11.  * of the OS API to start a thread (applies to OS/2 and Win32 only).
  12.  * Bullet itself does not use any C code or runtime support library code,
  13.  * but if you make use of SET_VECTORS_XB and use C code that calls the
  14.  * standard library, or call a C library routine from any thread, use
  15.  * beginthread().  See your compiler manual for details on why this is.
  16.  */
  17.  
  18. #include <io.h>
  19. #include <fcntl.h>
  20. #include <sys\types.h>
  21. #include <sys\stat.h>
  22. #include <sys\locking.h>
  23. #include <share.h>
  24. #include <direct.h>
  25. #include <errno.h>
  26.  
  27. #include <i86.h>
  28. #include <dos.h>
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <time.h>
  33. #include <string.h>
  34. #include <ctype.h>
  35. #include <time.h>
  36. #include <malloc.h>
  37.  
  38. #define LIBENTRY __cdecl
  39.  
  40. #ifndef VOID
  41.  #define VOID void
  42.  #define LONG long
  43.  typedef unsigned long ULONG;
  44.  typedef unsigned char *PSZ;
  45.  typedef const unsigned char *cPSZ;
  46.  typedef VOID *PVOID;
  47. #endif
  48.  
  49. // * For Bullet/X (DOSX32):
  50. // Of the following routines, these four MUST be provided to BULLETX.LIB:
  51. //
  52. // 1. LONG LIBENTRY BulletFree(VOID *baseAddr);
  53. // 2. LONG LIBENTRY BulletMalloc(ULONG bytes, VOID **baseAddrPtr);
  54. // 3. LONG LIBENTRY BulletGetMemoryAvail(void); // __WATCOM__
  55. // 4. LONG LIBENTRY BulletGetTmpDir(char *bufferPtr);
  56. //
  57. // Function pointers to these routines are to be set using SET_VECTORS_XB
  58. // (QSP.item = VECTOR_MALLOC; QSP.itemValue = (ULONG)&BulletMalloc();...)
  59. // If these are not set, when they are called the internal dispatcher returns
  60. // error = 1, function not supported.
  61. //
  62. // * For Bullet/2 and Bullet/95:
  63. // These may be used, or recoded, but they will never be as efficient as
  64. // the internal calls.  See SET_VECTORS_XB for more.
  65. //
  66. // Define FULL_COMPILER_SUPPORT to compile all routines in this module, or
  67. // leave undefined to compile just the four required routines (for DOSX32).
  68. //
  69. // ------------------------------------------------------------------------
  70. //
  71. // Routine protos listed below that end in "// __WATCOM__" include
  72. // compiler-specific code (usually intdos(), or a non-ANSI RTL call)
  73. // and need to be modified for use on other compilers.  In all cases
  74. // where __WATCOM__ is not defined, a suitable default is used, though
  75. // only suitable enough to compile and run.
  76.  
  77. // Watcom compiler flags are non-critical.  Since the code generated here
  78. // is not called often, you may compile with no optimizations without any
  79. // performance loss.  However, the calling convention must be C, with args
  80. // passed on the stack.  Since these are always called by pointer, the name
  81. // doesn't matter (i.e., leading _, or lack of, doesn't matter).  The
  82. // code must be compiled by a 32-bit flat-mode compiler (such as Watcom's
  83. // wcc386 compiler).  A suitable DOS-extender is also required.  Watcom's
  84. // package includes Tenberry's extender, but most any can be used, such as
  85. // Causeway and PMODE.  Borland's PowerPack may work, but it has not been
  86. // tested (Borland's extender is more of a Windows-based extender, rather
  87. // than a DOS-based extender; it is likely that intdos() calls are NOT
  88. // available using Borland's extender support, but with this source, you
  89. // probably will be able to do what is needed to get Bullet/X going just
  90. // fine.)
  91. //
  92. // Any structure packing must be on 1-byte aligns (i.e., no padding).
  93. //
  94. // Actual compile line used in testing (include set to watcom\h):
  95. // wcc386 ccdosfn.c -w4 -e25 -za -s -za -od -of -zl -zld -mf -4s -bt=DOS
  96.  
  97. // This code may be compiled to .obj form and added to the BULLETX.LIB file
  98. // using LIB/WLIB or simply added at LINK time to the final EXE, or it may
  99. // be left in source form and compiled along with the rest of your project.
  100. // Consult your compiler docs on how to build an EXE using an external LIB
  101. // file if you need more details.
  102.  
  103.  
  104.   // -------------------------------- //
  105.   // DOSX32 REQUIRED SUPPORT ROUTINES //
  106.   // -------------------------------- //
  107.  
  108.  
  109. #ifdef __cplusplus
  110.  extern "C" {
  111. #endif
  112.  
  113. LONG LIBENTRY BulletFree(VOID *baseAddr);
  114. LONG LIBENTRY BulletMalloc(ULONG bytes, VOID **baseAddrPtr);
  115. LONG LIBENTRY BulletGetMemoryAvail(void); // __WATCOM__
  116. LONG LIBENTRY BulletGetTmpDir(char *bufferPtr);
  117.  
  118. #ifdef __cplusplus
  119. }
  120. #endif
  121.  
  122. //:FREE MEMORY
  123. // Must be flat (ds=es=ss)
  124.  
  125. LONG LIBENTRY BulletFree(VOID *baseAddr) {
  126.  
  127.  free(baseAddr);
  128.  return 0;
  129.  
  130. }
  131.  
  132. //:ALLOCATE MEMORY
  133. // typical (0-filled required so use calloc)
  134.  
  135. LONG LIBENTRY BulletMalloc(ULONG bytes, VOID **baseAddrPtr) {
  136.  
  137.  *baseAddrPtr = calloc(bytes,1); // checked for NULL internally
  138.  return 0;
  139.  
  140. }
  141.  
  142. //:GET DOS MEMORY (available)
  143. // Watcom-specific compile returns _memmax(), else 128K
  144. // This is a required routine since internally it WOULD depend on
  145. // the BulletMalloc() (which used to be INT21/48/and for this call,
  146. // ebx was set to =1). This is not a critical-need routine in any case.
  147.  
  148. LONG LIBENTRY BulletGetMemoryAvail(void) {
  149.  
  150.  size_t mem;
  151.  
  152. #ifdef __WATCOMC__
  153.  
  154.  mem = _memmax();
  155.  
  156. #else
  157.  
  158.  mem=128*1024;
  159.  
  160. #endif
  161.  
  162.  return (LONG)mem;
  163. }
  164.  
  165.  
  166. //:GET TMP DIR
  167. // typical
  168.  
  169. LONG LIBENTRY BulletGetTmpDir(char *bufferPtr) {
  170.  
  171.  char *ePtr;
  172.  int eLen;
  173.  
  174.  ePtr=getenv("TMP");
  175.  if (ePtr != NULL) {
  176.  
  177.     eLen = strlen(ePtr);
  178.     if ((eLen != 0) && (eLen < 81-8)) {
  179.        strcpy(bufferPtr,ePtr);
  180.     }
  181.     else {
  182.        ePtr=NULL;
  183.     }
  184.  }
  185.  return (LONG)ePtr;   //return NULL (0) if TMP was not found
  186. }
  187.  
  188.  
  189.   //---------------------------------------------------------------//
  190.   //                                                               //
  191.   // The following routines are not required.  They may be used in //
  192.   // whole or in part.  Make them active by using SET_VECTORS_XB.  //
  193.   //                                                               //
  194.   //---------------------------------------------------------------//
  195.  
  196.  
  197. #ifdef FULL_COMPILER_SUPPORT
  198.  
  199. #ifdef __cplusplus
  200.    extern "C" {
  201. #endif
  202.  
  203. //----------------------------------------------------------------------------
  204. //[FILE ROUTINES] ============================================================
  205.  
  206. LONG LIBENTRY BulletCloseFile(ULONG handle);
  207. LONG LIBENTRY BulletCreateDir(cPSZ pathNamePtr);
  208. LONG LIBENTRY BulletCreateFile(cPSZ pathNamePtr);
  209. LONG LIBENTRY BulletDeleteFile(cPSZ pathNamePtr);
  210. LONG LIBENTRY BulletMoveFile(cPSZ orgPathNamePtr, cPSZ newPathNamePtr);
  211. LONG LIBENTRY BulletOpenFile(cPSZ pathNamePtr, LONG openMode, LONG *handlePtr);
  212. LONG LIBENTRY BulletReadFile(LONG handle, LONG *bytesPtr, VOID *bufferPtr);
  213. LONG LIBENTRY BulletSeekFile(LONG handle,LONG seekMode,LONG *offsetPtr);
  214. LONG LIBENTRY BulletUpdateDirEntry(LONG handle);
  215. LONG LIBENTRY BulletWriteFile(LONG handle, LONG *bytesPtr, VOID *bufferPtr);
  216.  
  217. //----------------------------------------------------------------------------
  218. //[NETWORK OS FUNCTIONS] =====================================================
  219.  
  220. LONG LIBENTRY BulletLockFile(LONG handle, LONG lockMode, LONG lockOffset, ULONG lockBytes, ULONG timeout);
  221. LONG LIBENTRY BulletIsDriveRemote(ULONG drive, ULONG *isRemotePtr, ULONG *isSharePtr); // __WATCOM__
  222. LONG LIBENTRY BulletIsFileRemote(ULONG handle, ULONG *isRemotePtr, ULONG *isSharePtr); // __WATCOM__
  223.  
  224. //----------------------------------------------------------------------------
  225. //[GENERAL OS FUNCTIONS] =====================================================
  226.  
  227. LONG LIBENTRY BulletGetSortTable (ULONG codePage, ULONG countryCode, VOID *bufferPtr, ULONG flags);
  228. LONG LIBENTRY BulletGetCountryInfo(ULONG *codePagePtr, ULONG *countryCodePtr, ULONG flags); // __WATCOM__
  229. LONG LIBENTRY BulletGetExtendedError(LONG ecode, ULONG *classPtr, ULONG *actionPtr, ULONG *locusPtr);
  230. LONG LIBENTRY BulletGetVersionDOS(ULONG *verPtr, ULONG *rezPtr, ULONG *maxPathPtr, ULONG *maxCompPtr); // __WATCOM__
  231. LONG LIBENTRY BulletSetHandleCount(ULONG *handlesPtr); // __WATCOM__
  232.  
  233. //----------------------------------------------------------------------------
  234. //[MISC OS FUNCTIONS] ========================================================
  235.  
  236. LONG LIBENTRY BulletGetTimeInfo(ULONG *timePtr, ULONG *datePtr, ULONG *dayPtr, LONG *tzPtr);
  237. LONG LIBENTRY BulletUpperCase(char *strPtr, ULONG strLen);
  238.  
  239. //----------------------------------------------------------------------------
  240. //[SEMAPHORE OS FUNCTIONS]====================================================
  241.  
  242. LONG LIBENTRY BulletCloseMutexSem(ULONG handle);
  243. LONG LIBENTRY BulletCreateMutexSem(ULONG rez1, ULONG *handlePtr, ULONG rez2, ULONG rez3);
  244. LONG LIBENTRY BulletRequestMutexSem(ULONG handle, ULONG timeout);
  245. LONG LIBENTRY BulletReleaseMutexSem(ULONG handle);
  246.  
  247. #ifdef __cplusplus
  248. }
  249. #endif
  250.  
  251.  
  252. //-------------------------------
  253. // Convert CLIB errno to OS error
  254. // finer conversion is possible to non-90xx
  255. // local use
  256.  
  257. int LocalGetErrorCC(void) {
  258.  
  259.  #define bltEZERO     0    /* 0  No error */
  260.  #define bltENOENT    2    /* 1  No such file or directory */
  261.  #define bltE2BIG     9002 /* 2  Arg list too big */
  262.  #define bltENOEXEC   9003 /* 3  Exec format error */
  263.  #define bltEBADF     6    /* 4  Bad file number */
  264.  #define bltENOMEM    8    /* 5  Not enough memory */
  265.  #define bltEACCES    5    /* 6  Permission denied */
  266.  #define bltEEXIST    80   /* 7  File exists */
  267.  #define bltEXDEV     9008 /* 8  Cross-device link */
  268.  #define bltEINVAL    9009 /* 9  Invalid argument */
  269.  #define bltENFILE    9010 /* 10 File table overflow */
  270.  #define bltEMFILE    4    /* 11 Too many open files */
  271.  #define bltENOSPC    39   /* 12 No space left on device */
  272.                            /*    File locking error */
  273.  #define bltEDEADLK   5    /* 15 Resource deadlock would occur */
  274.  #define bltEDEADLOCK 5    /* 15 ... */
  275.  #define bltEINTR     9016 /* 16 interrupt */
  276.  #define bltECHILD    9017 /* 17 Child does not exist */
  277.                            /*    POSIX errors */
  278.  #define bltEAGAIN    9018 /* 18 Resource unavailable, try again */
  279.  #define bltEBUSY     142  /* 19 Device or resource busy */
  280.  #define bltEFBIG     9020 /* 20 File too large */
  281.  #define bltEIO       31   /* 21 I/O error */
  282.  #define bltEISDIR    9022 /* 22 Is a directory */
  283.  #define bltENOTDIR   9023 /* 23 Not a directory */
  284.  #define bltEMLINK    9024 /* 24 Too many links */
  285.  #define bltENOTBLK   9025 /* 25 Block device required */
  286.  #define bltENOTTY    9026 /* 26 Not a character device */
  287.  #define bltENXIO     9027 /* 27 No such device or address */
  288.  #define bltEPERM     9028 /* 28 Not owner */
  289.  #define bltEPIPE     9029 /* 29 Broken pipe */
  290.  #define bltEROFS     5    /* 30 Read-only file system */
  291.  #define bltESPIPE    9031 /* 31 Illegal seek */
  292.  #define bltESRCH     9032 /* 32 No such process */
  293.  #define bltETXTBSY   9033 /* 33 Text file busy */
  294.  #define bltEFAULT    9034 /* 34 Bad address */
  295.  #define bltENAMETOOLONG  9035 /* 35 Name too long */
  296.  #define bltENODEV    9036 /* 36 No such device */
  297.  #define bltENOLCK    9037 /* 37 No locks available in system */
  298.  #define bltENOSYS    1    /* 38 Unknown system call */
  299.  #define bltENOTEMPTY 9039 /* 39 Directory not empty */
  300.  
  301.  int rez;
  302.  
  303.  rez=errno;
  304.  switch (rez) {
  305.   case EZERO        : rez=bltEZERO       ;break;
  306.   case ENOENT       : rez=bltENOENT      ;break;
  307.   case E2BIG        : rez=bltE2BIG       ;break;
  308.   case ENOEXEC      : rez=bltENOEXEC     ;break;
  309.   case EBADF        : rez=bltEBADF       ;break;
  310.   case ENOMEM       : rez=bltENOMEM      ;break;
  311.   case EACCES       : rez=bltEACCES      ;break;
  312.   case EEXIST       : rez=bltEEXIST      ;break;
  313.   case EXDEV        : rez=bltEXDEV       ;break;
  314.   case EINVAL       : rez=bltEINVAL      ;break;
  315.   case ENFILE       : rez=bltENFILE      ;break;
  316.   case EMFILE       : rez=bltEMFILE      ;break;
  317.   case ENOSPC       : rez=bltENOSPC      ;break;
  318.   //case EDEADLK      : rez=bltEDEADLK     ;break; // same as EDEADLOCK
  319.   case EDEADLOCK    : rez=bltEDEADLOCK   ;break;
  320.   case EINTR        : rez=bltEINTR       ;break;
  321.   case ECHILD       : rez=bltECHILD      ;break;
  322.  
  323.   case EAGAIN       : rez=bltEAGAIN      ;break;
  324.   case EBUSY        : rez=bltEBUSY       ;break;
  325.   case EFBIG        : rez=bltEFBIG       ;break;
  326.   case EIO          : rez=bltEIO         ;break;
  327.   case EISDIR       : rez=bltEISDIR      ;break;
  328.   case ENOTDIR      : rez=bltENOTDIR     ;break;
  329.   case EMLINK       : rez=bltEMLINK      ;break;
  330.   case ENOTBLK      : rez=bltENOTBLK     ;break;
  331.   case ENOTTY       : rez=bltENOTTY      ;break;
  332.   case ENXIO        : rez=bltENXIO       ;break;
  333.   case EPERM        : rez=bltEPERM       ;break;
  334.   case EPIPE        : rez=bltEPIPE       ;break;
  335.   case EROFS        : rez=bltEROFS       ;break;
  336.   case ESPIPE       : rez=bltESPIPE      ;break;
  337.   case ESRCH        : rez=bltESRCH       ;break;
  338.   case ETXTBSY      : rez=bltETXTBSY     ;break;
  339.   case EFAULT       : rez=bltEFAULT      ;break;
  340.   case ENAMETOOLONG : rez=bltENAMETOOLONG;break;
  341.   case ENODEV       : rez=bltENODEV      ;break;
  342.   case ENOLCK       : rez=bltENOLCK      ;break;
  343.   case ENOSYS       : rez=bltENOSYS      ;break;
  344.   case ENOTEMPTY    : rez=bltENOTEMPTY   ;break;
  345.   default: rez=9099;
  346.  }
  347.  return rez;
  348. }
  349.  
  350.  
  351.  
  352.  
  353. //----------------------------------------------------------------------------
  354. //[FILE ROUTINES] ============================================================
  355.  
  356. //:CLOSE FILE
  357. // typical
  358.  
  359. LONG LIBENTRY BulletCloseFile(ULONG handle) {
  360.  
  361.  int rez;
  362.  
  363.  rez = close((int)handle);
  364.  if (rez== -1) rez=LocalGetErrorCC();
  365.  return (LONG)rez;
  366. }
  367.  
  368.  
  369. //:CREATE DIRECTORY
  370. // typical
  371.  
  372. LONG LIBENTRY BulletCreateDir(cPSZ pathNamePtr) {
  373.  
  374.  int rez;
  375.  
  376.  rez = mkdir(pathNamePtr);
  377.  if (rez== -1) rez=LocalGetErrorCC();
  378.  return (LONG)rez;
  379. }
  380.  
  381.  
  382. //:CREATE FILE
  383. // typical
  384.  
  385. LONG LIBENTRY BulletCreateFile(cPSZ pathNamePtr) {
  386.  
  387.  int rez;
  388.  int handle;
  389.  
  390.  handle = sopen(pathNamePtr,
  391.                 O_CREAT | O_EXCL | O_RDWR | O_BINARY,
  392.                 SH_DENYRW,
  393.                 S_IREAD | S_IWRITE);
  394.  if (handle== -1) {
  395.     rez=LocalGetErrorCC();
  396.  }
  397.  else {
  398.     close(handle);   // only create it, so close after a good create
  399.     rez=0;
  400.  }
  401.  return (LONG)rez;
  402. }
  403.  
  404.  
  405. //:DELETE FILE
  406. // typical
  407.  
  408. LONG LIBENTRY BulletDeleteFile(cPSZ pathNamePtr) {
  409.  
  410.  int rez;
  411.  
  412.  rez = remove(pathNamePtr);
  413.  if (rez== -1) rez=LocalGetErrorCC();
  414.  return (LONG)rez;
  415. }
  416.  
  417.  
  418. //:RENAME (Move) FILE
  419. // typical
  420.  
  421. LONG LIBENTRY BulletMoveFile(cPSZ orgPathNamePtr, cPSZ newPathNamePtr) {
  422.  
  423.  int rez;
  424.  
  425.  rez = rename(orgPathNamePtr, newPathNamePtr);
  426.  if (rez== -1) rez=LocalGetErrorCC();
  427.  return (LONG)rez;
  428. }
  429.  
  430.  
  431. //:OPEN FILE
  432. // if handle <=2 is returned to Bullet, Bullet will leave the handle
  433. // alone and issue ERR_SYSTEM_HANDLE (8305) returned for rez.  Your
  434. // app level code (OPEN_DATA_XB, etc.) should reissue the open request.
  435.  
  436. LONG LIBENTRY BulletOpenFile(cPSZ pathNamePtr, LONG openMode, LONG *handlePtr) {
  437.  
  438.  int rez;
  439.  int handle;
  440.  int oflag, shflag;
  441.  
  442.  *(handlePtr)=0;
  443.  
  444.  switch (openMode & 0x03) {
  445.   case 0: oflag = O_RDONLY | O_BINARY; break;
  446.   case 1: oflag = O_WRONLY | O_BINARY; break;
  447.   default:oflag = O_RDWR   | O_BINARY; break;
  448.  }
  449.  
  450.  switch (openMode & 0x70) {             // no-inherit is not supported by sopen()
  451.   case 0x10: shflag = SH_DENYRW; break; // deny read-write
  452.   case 0x20: shflag = SH_DENYWR; break; // deny write
  453.   case 0x30: shflag = SH_DENYRD; break; // deny read
  454.   case 0x40: shflag = SH_DENYNO; break; // deny none
  455.   default: shflag = SH_DENYNO;   break; // SH_COMPAT is not a good idea so deny none when case==0
  456.  }
  457.  
  458.  handle = sopen(pathNamePtr, oflag, shflag);
  459.  if (handle== -1) {
  460.     rez=LocalGetErrorCC();
  461.  }
  462.  else {
  463.     *(handlePtr)=(LONG)handle;
  464.     rez=0;
  465.  }
  466.  return (LONG)rez;
  467. }
  468.  
  469.  
  470. //:READ FILE
  471. // extender typically handles requests for >64K bytes  --if not, shrink
  472. // Bullet pack/reindex buffers so that no single read request is larger than
  473. // 65520 bytes (or 32767 for some C RTLs)
  474. //
  475. // if bytesRead is not the same as bytes-requested this routine does
  476. // NOT return an error (simply return the bytes actually read)
  477.  
  478. LONG LIBENTRY BulletReadFile(LONG handle, LONG *bytesPtr, VOID *bufferPtr) {
  479.  
  480.  int rez;
  481.  int bytesRead;
  482.  
  483.  bytesRead = read((int)handle, bufferPtr, (unsigned int) *(bytesPtr));
  484.  if (bytesRead== -1) {
  485.     rez=LocalGetErrorCC();
  486.  }
  487.  else {
  488.     *(bytesPtr)=(LONG)bytesRead;
  489.     rez=0;
  490.  }
  491.  return (LONG)rez;
  492. }
  493.  
  494.  
  495. //:SEEK TO FILE POSITION
  496. // typical
  497.  
  498. LONG LIBENTRY BulletSeekFile(LONG handle,LONG seekMode,LONG *offsetPtr) {
  499.  
  500.  int rez;
  501.  long currPos;
  502.  
  503.  currPos = lseek((int)handle, *(offsetPtr), (int)seekMode);
  504.  if (currPos== -1) {
  505.     rez=LocalGetErrorCC();
  506.  }
  507.  else {
  508.     *(offsetPtr)=currPos;
  509.     rez=0;
  510.  }
  511.  return (LONG)rez;
  512. }
  513.  
  514.  
  515. //:UPDATE DIR ENTRY
  516. // typical
  517.  
  518. LONG LIBENTRY BulletUpdateDirEntry(LONG handle) {
  519.  
  520.  int rez;
  521.  int handleCommit;
  522.  
  523.  handleCommit=dup(handle);
  524.  if (handleCommit== -1) {
  525.     rez=LocalGetErrorCC();
  526.  }
  527.  else {
  528.     close(handleCommit);
  529.     rez=0;
  530.  }
  531.  return (LONG)rez;
  532. }
  533.  
  534.  
  535. //:WRITE FILE
  536. // extender typically handles requests for >64K bytes  --if not, shrink
  537. // Bullet pack/reindex buffers so that no single read request is larger than
  538. // 65520 bytes (or 32767 for some C RTLs)
  539. //
  540. // if bytesWritten is not the same as bytes-requested this routine does
  541. // NOT return an error (simply return the bytes actually written)
  542. // (a ERR_DISK_FULL is generated internally by Bullet if this is the case)
  543. //
  544. // If *bytesPtr=0 (write 0 bytes) file is to be truncated at its current
  545. // position.  In DOS, this is the case (i.e., the OS does this when bytes-to-write
  546. // is 0).  chsize() may be an alternate option when 0.
  547.  
  548. LONG LIBENTRY BulletWriteFile(LONG handle, LONG *bytesPtr, VOID *bufferPtr) {
  549.  
  550.  int rez;
  551.  int bytesWritten;
  552.  
  553.  bytesWritten = write((int)handle, bufferPtr, (unsigned int) *(bytesPtr));
  554.  if (bytesWritten== -1) {
  555.     rez=LocalGetErrorCC();
  556.  }
  557.  else {
  558.     *(bytesPtr)=(LONG)bytesWritten;
  559.     rez=0;
  560.  }
  561.  return (LONG)rez;
  562. }
  563.  
  564.  
  565.  
  566.  
  567. //----------------------------------------------------------------------------
  568. //[NETWORK OS FUNCTIONS] =====================================================
  569.  
  570. //:LOCK/UNLOCK FILE
  571. // lockMode: bit0=0 lock
  572. //           bit0=1 unlock
  573. //    n/a    bit1=0 exclusive access to locked region by process (R/W)
  574. //    n/a    bit1=1 read access to locked region, but not write for any
  575. //    n/a    bit2=1 atomic lock operation (unlock then lock, for relock only)
  576. //    n/a = not available in DOSX32
  577.  
  578. LONG LIBENTRY BulletLockFile(LONG handle, LONG lockMode, LONG lockOffset, ULONG lockBytes, ULONG timeout) {
  579.  
  580.  int rez, rez2;
  581.  int lockType;
  582.  
  583.  LONG currPos=0;
  584.  LONG newPos;
  585.  
  586.  if ((lockMode & 1)==1) {
  587.     lockType=LK_UNLCK;     // unlock if bit0=1
  588.  }
  589.  else {
  590.     lockType=LK_NBLCK;     // lock if bit0=1 (non-blocking, or use timeout as basis to block)
  591.  }
  592.  
  593.  // locking() used over lock() since more likely supported by the RTL
  594.  
  595.  rez = BulletSeekFile(handle,1,&currPos);
  596.  if (rez==0) {
  597.  
  598.     newPos = lockOffset;
  599.     rez = BulletSeekFile(handle,0,&newPos);
  600.     if (rez==0) {
  601.        rez = locking(handle,lockType,lockBytes);
  602.        if (rez==-1) rez=LocalGetErrorCC();
  603.     }
  604.  
  605.     //even though Bullet file operations are atomic, the position is restored
  606.     rez2 = BulletSeekFile(handle,0,&currPos); // restore position
  607.  
  608.     if (rez==0) rez=rez2;
  609.  }
  610.  return (LONG)rez;
  611.  
  612.  timeout;  // ref it-unreachable-use it if you can
  613. }
  614.  
  615.  
  616. //:QUERY DRIVE REMOTE
  617. // used for informational use only (non-critical)
  618. // Requires making INT call if not otherwise supported by a compiler call.
  619. // The source below compiles with a Watcom compiler (10a, for example), if not:
  620. //
  621. // This code sets remote and share flags to 1, indicating that the file
  622. // is remote and that SHARE.EXE (or compatible) is installed.  The purpose
  623. // is information, and is used to determine whether locking is required.
  624. // Since it's better to lock and not need to than to not lock and need to,
  625. // this code returns 1 in both cases.  If SHARE is not installed, a run-time
  626. // error is returned by BulletLockFile(), above (try it).  This may also
  627. // happen if run in a Windows DOS box since Windows always reports that
  628. // SHARE is installed (it should be if it isn't).
  629.  
  630. LONG LIBENTRY BulletIsDriveRemote(ULONG drive, ULONG *isRemotePtr, ULONG *isSharePtr) {
  631.  
  632.  int rez;
  633.  
  634. #ifdef __WATCOMC__
  635.  
  636.  union REGS iregs, oregs;
  637.  
  638.  *(isRemotePtr)=1;
  639.  *(isSharePtr)=1;
  640.  
  641.  iregs.x.eax = 0x4409;
  642.  iregs.x.ebx = drive;   // 0=current/default, 1=A:, 2=B:, 3=C:...
  643.  iregs.x.edx = 0;
  644.  rez = intdos(&iregs, &oregs);
  645.  if ((oregs.x.cflag & 1)==0) {
  646.     if ((oregs.x.edx & (1 << 12))==1) *(isRemotePtr)=1;  // bit12=1 then remote
  647.     rez = 0;
  648.  }
  649.  
  650.  oregs.x.eax = -1;      // init to non-zero for 0-compare after call
  651.  iregs.x.eax = 0x1000;  // ignore error since not likely, and it won't matter
  652.  int386(0x2F, &iregs, &oregs);
  653.  if ((oregs.h.al)==0) {  // installed only if al=FF
  654.     *(isSharePtr)=0;
  655.  }
  656.  
  657. #else
  658.  
  659.  *(isRemotePtr)=1;
  660.  *(isSharePtr)=1;
  661.  rez=0;
  662.  
  663. #endif
  664.  
  665.  return (LONG)rez;
  666. }
  667.  
  668.  
  669. //:QUERY FILE REMOTE
  670. // see notes for QUERY DRIVE REMOTE
  671.  
  672. LONG LIBENTRY BulletIsFileRemote(ULONG handle, ULONG *isRemotePtr, ULONG *isSharePtr) {
  673.  
  674.  int rez;
  675.  
  676. #ifdef __WATCOMC__
  677.  
  678.  union REGS iregs, oregs;
  679.  
  680.  *(isRemotePtr)=1;
  681.  *(isSharePtr)=1;
  682.  
  683.  iregs.x.eax = 0x440A;
  684.  iregs.x.ebx = handle;
  685.  iregs.x.edx = 0;
  686.  rez = intdos(&iregs, &oregs);
  687.  if ((oregs.x.cflag & 1)==0) {
  688.     if ((oregs.x.edx & (1 << 15))==1) *(isRemotePtr)=1;  // bit15=1 then remote
  689.     rez = 0;
  690.  }
  691.  
  692.  oregs.x.eax = -1;      // init to non-zero for 0-compare after call
  693.  iregs.x.eax = 0x1000;  // ignore error since not likely, and it won't matter
  694.  int386(0x2F, &iregs, &oregs);
  695.  if ((oregs.h.al)==0) {  // installed only if al=FF
  696.     *(isSharePtr)=0;
  697.  }
  698.  
  699. #else
  700.  
  701.  *(isRemotePtr)=1;
  702.  *(isSharePtr)=1;
  703.  rez=0;
  704.  
  705. #endif
  706.  
  707.  return (LONG)rez;
  708. }
  709.  
  710.  
  711.  
  712.  
  713. //----------------------------------------------------------------------------
  714. //[GENERAL OS FUNCTIONS] =====================================================
  715.  
  716.  
  717.  
  718. //:GET COLLATE SEQUENCE
  719. //default is for US codePage
  720.  
  721. LONG LIBENTRY BulletGetSortTable (ULONG codePage, ULONG countryCode, VOID *bufferPtr, ULONG flags) {
  722.  
  723.  // OEM cp=437 table along MS-DOS, OS/2 lines (similar to Windows OEM)
  724.  
  725.  static char sortTableOEM[] = {
  726. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  727. 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
  728. 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
  729. 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
  730. 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
  731. 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
  732. 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
  733. 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x7B,0x7C,0x7D,0x7E,0x7F,
  734. 0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41,
  735. 0x45,0x41,0x41,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x24,0x24,0x24,0x24,0x24,
  736. 0x41,0x49,0x4F,0x55,0x4E,0x4E,0xA6,0xA7,0x3F,0xA9,0xAA,0xAB,0xAC,0x21,0x22,0x22,
  737. 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
  738. 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
  739. 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
  740. 0xE0,0x53,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
  741. 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
  742. };
  743.  
  744.  // ANSI cp=1252 table along Windows lines
  745.  
  746.  static char sortTableANSI[] = {
  747. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  748. 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
  749. 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
  750. 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
  751. 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
  752. 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
  753. 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
  754. 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x7B,0x7C,0x7D,0x7E,0x7F,
  755. 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
  756. 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F,
  757. 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
  758. 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
  759. 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
  760. 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
  761. 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
  762. 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F
  763. };
  764.  
  765.  if (flags & 1) {
  766.  
  767.     // USE_ANSI_SET flag in CREATE_INDEX_XB
  768.  
  769.     memmove(bufferPtr,sortTableANSI,256);
  770.  }
  771.  else {
  772.     memmove(bufferPtr,sortTableOEM,256);
  773.  }
  774.  return 0;
  775.  
  776.  codePage;
  777.  countryCode;
  778.  flags;
  779.  
  780. #if 0
  781.  
  782.  // --------------------------------------------------------------------------
  783.  // the original assembly is shown for reference if you want
  784.  // to do inline assembly to get the DOS table -- results
  785.  // may be less than perfect (DOS may return an invalid table)
  786.  // NOTE that this is the  DOSX32  original version
  787.  // and both
  788.  
  789. ;--------------------
  790. ;GET COLLATE SEQUENCE
  791. ; in: ecx=code page ID
  792. ;     edx=country code
  793. ;     edi->buffer to store sequence table (256 bytes)
  794. ;     esi=OEM (0) or ANSI (1) flag (for Windows use only, selects char set)
  795. ;out: eax=0, or error if CF=1
  796. ;use:
  797. ;nts: uses DPMI call to ax=6 verify selector!
  798. ;     if ERR_216506 returned, instruct user to provide own collate table
  799. ;DOS4GW does return 6,seg:off, but only a 16-bit offset! (06,ofs16,selector)
  800.  
  801. PROC
  802.  LOCAL \
  803.  sBuffer[20]:DWORD
  804.  
  805.  mov     ebx,ecx         ;ebx=cp / edx=cc
  806.  mov     ecx,5           ;get 5 bytes worth
  807.  mov     ax,6506h        ;es:edi->buffer (use dest buffer for a sec)
  808.  int 21h
  809.  jc      ExitNotSupported
  810.  cmp     BPTR [edi],6    ;valid identifier?
  811.  jne     ExitNotSupported ;no!
  812.  
  813.  movzx   esi,WPTR [edi+1];16-bit offset so movzx
  814.  mov     bx,WPTR [edi+3] ;and selector to bx for testing
  815.  
  816.  mov     ax,6            ;DPMI Get Segment Base Address
  817.  int 31h                 ;used only to validate selector
  818.  jc      ExitNotSupported
  819.  
  820.  push    ds              ;(save ds)
  821.  mov     ds,bx           ;ds:esi->table size word
  822.  movzx   ecx,WPTR [esi]  ;get size in bytes
  823.  cmp     ecx,256         ;valid size?
  824.  jne     ExitNS2         ;no
  825.  add     esi,2
  826.  shr     ecx,2           ;move dwords at a time (256/4=64 dwords)
  827.  rep movsd
  828.  pop     ds              ;(back ds)
  829.  sub     eax,eax
  830. ExitGen:
  831.  ret
  832.  
  833. ExitNotSupported:
  834.  mov     eax,ERR_216506 ;(ERR_216506 = 8256)
  835.  stc
  836.  jmp     ExitGen
  837. ExitNS2:
  838.  pop     ds              ;(back ds)
  839.  jmp     ExitNotSupported
  840. ENDP
  841.  
  842.   // -------------------------------------------------------------------------
  843.  
  844. #endif
  845. }
  846.  
  847.  
  848. //:GET COUNTRY INFO
  849. // requires WATCOM-specific intdos() support, else returns parms same as args
  850.  
  851. LONG LIBENTRY BulletGetCountryInfo(ULONG *codePagePtr, ULONG *countryCodePtr, ULONG flags) {
  852.  
  853.  int rez;
  854.  ULONG cc, cp;
  855.  
  856. #ifdef __WATCOMC__
  857.  
  858.  char buffer[44];
  859.  unsigned short *tmpPtr;
  860.  
  861.  union REGS iregs, oregs;
  862.  
  863.  iregs.x.eax = 0x6501;
  864.  iregs.x.ecx = 40;
  865.  iregs.x.edi = (ULONG)(&buffer)+3;  // for alignment
  866.  rez = intdos(&iregs, &oregs);
  867.  if ((oregs.x.cflag & 1)==0) {
  868.  
  869.     tmpPtr = (unsigned short*) &buffer[3];
  870.     cc = *(tmpPtr);
  871.     cp = *(++tmpPtr);
  872.  }
  873.  else {
  874.     rez = 8251;   // Bullet ERR_216501 (extender support lacking)
  875.  }
  876.  
  877. #else
  878.  
  879.     // one way to do it (easier to change this way since common exit assigns done)
  880.  
  881.     cc = *countryCodePtr;
  882.     cp = *codePagePtr;
  883.     rez=0;
  884.  
  885. #endif
  886.  
  887.  if (*countryCodePtr==0) *countryCodePtr = cc;
  888.  if (*codePagePtr==0) *codePagePtr = cp;
  889.  return (LONG)rez;
  890.  
  891.  flags;
  892. }
  893.  
  894.  
  895. //:GET EXTENDED ERROR
  896. // for informational use; not supported so returned *Ptr==0
  897.  
  898. LONG LIBENTRY BulletGetExtendedError(LONG ecode, ULONG *classPtr, ULONG *actionPtr, ULONG *locusPtr) {
  899.  
  900.  *classPtr=0;
  901.  *actionPtr=0;
  902.  *locusPtr=0;
  903.  return 0;
  904.  
  905.  ecode;
  906. }
  907.  
  908.  
  909. //:GET DOS VERSION
  910. // Watcom-specific compile uses intdos(), else returns version 500 (for DOS 5.0)
  911.  
  912. LONG LIBENTRY BulletGetVersionDOS(ULONG *verPtr, ULONG *rezPtr, ULONG *maxPathPtr, ULONG *maxCompPtr) {
  913.  
  914.  int rez;
  915.  
  916. #ifdef __WATCOMC__
  917.  
  918.  union REGS iregs, oregs;
  919.  
  920.  iregs.x.eax = 0x3000;
  921.  rez = intdos(&iregs, &oregs);
  922.  *verPtr = (iregs.h.al * 100) + (iregs.h.ah);
  923.  
  924. #else
  925.  
  926.  *verPtr = 500;   // assume DOS 5.0
  927.  rez = 0;
  928.  
  929. #endif
  930.  
  931.  strncpy((char *)rezPtr,"2TLB",4);
  932.  *maxPathPtr = 81;
  933.  *maxCompPtr = 8; // preferred over 11
  934.  return (LONG)rez;
  935. }
  936.  
  937.  
  938.  
  939.  
  940. //:SET HANDLE COUNT
  941. // Watcom-specific compile uses intdos(), else no action (max 15 handles then)
  942. //
  943. // *handlesPtr is to return the max number of handles available
  944. // if *handlesPtr==0 on entry, return max number of handles available
  945. // in DOS, this is not a supported service, so tracked internally
  946. // (i.e., leave value in *handlesPtr as is)
  947. //
  948. // Note: Even though Watcom's _grow_handle() does return the max
  949. // handles that can be open (with restrictions), it returns 256
  950. // when 255 is used as its arg.  DOS nevers uses handle FF since
  951. // this is reserved for the 'unused' slot marker in the file
  952. // tables, so the max possible is 255 (numbered 0-254).  A safe
  953. // bet here is to let Bullet handles this case, and just leave
  954. // *handlesPtr as-is.
  955.  
  956. LONG LIBENTRY BulletSetHandleCount(ULONG *handlesPtr) {
  957.  
  958.  int rez;
  959.  
  960. #ifdef __WATCOMC__
  961.  
  962.  // The Watcom RTL 'open' support requires that _grow_handles()
  963.  // be used; simply using DOS INT21/67 is not sufficient, even
  964.  // though the open support routines used DOS handles directly
  965.  // (this may be related to the extender)
  966.  //
  967.  //union REGS iregs, oregs;
  968.  //
  969.  //iregs.x.eax = 0x6700;
  970.  //iregs.x.ebx = *handlesPtr;
  971.  //rez = intdos(&iregs, &oregs);
  972.  //if ((oregs.x.cflag & 1)==0) rez=0;
  973.  
  974.  rez = _grow_handles((int)*handlesPtr);
  975.  if (rez== -1) {
  976.     rez=LocalGetErrorCC();
  977.  }
  978.  else {
  979.     rez=0;
  980.  }
  981.  
  982. #else
  983.  
  984.  // you won't be able to open more than 15 or so handles concurrently
  985.  // unless this is coded for your compiler -- also be sure to increase
  986.  // FILES= in config.sys (set to no more than FILES=255)
  987.  
  988.  rez=0;
  989.  
  990. #endif
  991.  
  992.  return (LONG)rez;
  993. }
  994.  
  995.  
  996.  
  997.  
  998. //----------------------------------------------------------------------------
  999. //[MISC OS FUNCTIONS] ========================================================
  1000.  
  1001. //:GET DATE/TIME
  1002. // typical
  1003.  
  1004. LONG LIBENTRY BulletGetTimeInfo(ULONG *timePtr, ULONG *datePtr, ULONG *dayPtr, LONG *tzPtr) {
  1005.  
  1006.  #define daTZ  0xFF00
  1007.  
  1008.  struct tm *daTime;
  1009.  time_t daTicks;
  1010.  
  1011.  static int huns = 99;
  1012.  
  1013.  // hundreths are needed so simulate
  1014.  
  1015.  huns++;
  1016.  if (huns==100) huns=0;
  1017.  
  1018.  time(&daTicks);
  1019.  daTime = localtime(&daTicks);
  1020.  
  1021.  *(timePtr) = (daTime->tm_hour) + (daTime->tm_min << 8) + (daTime->tm_sec << 16) + (huns << 24);
  1022.  *(datePtr) = (daTime->tm_year +1900) + ((daTime->tm_mon+1) << 16) + (daTime->tm_mday << 24);
  1023.  *(dayPtr)  = (daTime->tm_wday);
  1024.  *(tzPtr)   = (LONG) daTZ;
  1025.  
  1026.  return 0;
  1027. }
  1028.  
  1029.  
  1030. //:UPPERCASE STRING
  1031. // Used to upper-case fieldnames, key expression, and value in UPPER().
  1032. // This likely will not work for char > 127, but this should not pose
  1033. // a problem since field names (and hence, key expression and UPPER()
  1034. // value) should be standard ASCII only.
  1035. // Filenames do NOT have their case changed (that's FILE names).
  1036. // String likely is NOT 0-terminated,
  1037. // String will NOT contain embedded 0s.
  1038.  
  1039. LONG LIBENTRY BulletUpperCase(char *strPtr, ULONG strLen) {
  1040.  
  1041.  while (strLen--) {
  1042.     toupper(*strPtr++);
  1043.  }
  1044.  
  1045.  return 0;
  1046. }
  1047.  
  1048.  
  1049.  
  1050.  
  1051. //----------------------------------------------------------------------------
  1052. //[SEMAPHORE OS FUNCTIONS]====================================================
  1053.  
  1054. //:CLOSE MUTEX SEMAPHORE
  1055. // used at EXIT_XB
  1056.  
  1057. LONG LIBENTRY BulletCloseMutexSem(ULONG handle) {
  1058.  
  1059.  return 0;
  1060.  
  1061.  handle;
  1062. }
  1063.  
  1064.  
  1065. //:CREATE MUTEX SEMAPHORE
  1066. // used at first Bullet call
  1067.  
  1068. LONG LIBENTRY BulletCreateMutexSem(ULONG rez1, ULONG *handlePtr, ULONG rez2, ULONG rez3) {
  1069.  
  1070.  *handlePtr=1;  // return non-zero to prevent later calls
  1071.  return 0;
  1072.  
  1073.  rez1;   // passed=0, unnamed semaphore
  1074.  rez2;   // passed=0, not shared with other processes
  1075.  rez3;   // passed=0, initiallly unowned semaphore
  1076.  handlePtr;
  1077. }
  1078.  
  1079.  
  1080. //:REQUEST MUTEX SEMAPHORE
  1081. // used at each Bullet call
  1082.  
  1083. LONG LIBENTRY BulletRequestMutexSem(ULONG handle, ULONG timeout) {
  1084.  
  1085.  return 0;
  1086.  
  1087.  handle;
  1088.  timeout;   // passed=as set by sysvar
  1089. }
  1090.  
  1091.  
  1092. //:RELEASE MUTEX SEMAPHORE
  1093. // used at each Bullet call
  1094.  
  1095. LONG LIBENTRY BulletReleaseMutexSem(ULONG handle) {
  1096.  
  1097.  return 0;
  1098.  
  1099.  handle;
  1100. }
  1101.  
  1102. #endif // #ifdef FULL_COMPILER_SUPPORT
  1103.  
  1104. // <EOF>
  1105.