home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / ramfs102.zip / src / util.c < prev    next >
C/C++ Source or Header  |  2002-09-28  |  8KB  |  336 lines

  1. #include "includes.h"
  2.  
  3. #include <stdarg.h>
  4. #include <stdio.h>
  5. #include <dos.h>
  6.  
  7. #define MIN(a,b)  ((a) < (b) ? (a) : (b))
  8. #ifndef MK_FP
  9.  #define MK_FP(seg,ofs)  ((void FAR *)(((unsigned long)seg<<16)+(unsigned long)ofs))
  10. #endif
  11.  
  12. PFN near DevHlp;
  13. PGINFOSEG near pGiseg;
  14.  
  15.  
  16. void _cdecl abort (void) {}
  17. void _cdecl _RealCvtVector (void) {}
  18. void _cdecl _ScanTodVector (void) {}
  19. char _cdecl _cvtfak = 0;
  20. unsigned char   _cdecl inportb( unsigned __portid );
  21. void            _cdecl outportb( unsigned __portid, unsigned char __value );
  22.  
  23.  
  24. /* static */
  25. volatile char InRamfs = FALSE;
  26.  
  27.  
  28. #ifdef DEBUG
  29.  
  30. char debugging = TRUE;
  31.  
  32.  
  33. int _cdecl debug_printf (const char _ds *format, ...)
  34. {
  35.   va_list args;
  36.   char buf [256];
  37.   int len;
  38.   int i;
  39.  
  40.   if (!debugging)
  41.     return 0;
  42.  
  43.   va_start (args, format);
  44.   len = vsprintf (buf, format, args);
  45.   for (i=0; i<len; i++)
  46.   {
  47.     while (!(inportb (0x2FD) & 0x20))
  48.       ;
  49.     outportb (0x2F8, buf[i]);
  50.   }
  51.   va_end (args);
  52.   return len;
  53. }
  54.  
  55. #endif
  56.  
  57.  
  58.  
  59.  
  60. ULONG UtilGetDateTime (void)
  61. {
  62.   USHORT dateNow;
  63.   USHORT timeNow;
  64.  
  65.   do
  66.   {
  67.     dateNow = ((pGiseg->year-1980) <<  9) |
  68.            (pGiseg->month      <<  5) |
  69.            (pGiseg->day        <<  0);
  70.  
  71.     timeNow =  (pGiseg->hour    << 11) |
  72.            (pGiseg->minutes <<  5) |
  73.            (pGiseg->seconds >>  1);
  74.   }
  75.   while 
  76.   (
  77.     dateNow != (((pGiseg->year-1980) <<  9) |
  78.            (pGiseg->month      <<  5) |
  79.            (pGiseg->day        <<  0))
  80.     ||
  81.     timeNow != ((pGiseg->hour    << 11) |
  82.            (pGiseg->minutes <<  5) |
  83.            (pGiseg->seconds >>  1))
  84.   );
  85.   return dateNow + ((ULONG)timeNow << 16);
  86. }
  87.  
  88.  
  89.  
  90.  
  91. /* static */
  92. int UtilScanDir (FLAT flatBlkDir, FLAT _ss *pflatEntry, PDIRENTRY pEntry,
  93.          char *pachName, int cbName)
  94. {
  95.   BLOCK BlkDir;
  96.   FLAT  flatEnd;
  97.   char  szUpName[256];
  98.   char  szUpCurName[256];
  99.   int   cbCurName;
  100.   int   rc;
  101.  
  102.   memcpy (szUpName, pachName, cbName);
  103.   szUpName[cbName] = '\0';
  104.   FSH_UPPERCASE (szUpName, 256, szUpName);
  105.  
  106.   VMReadBlk (&BlkDir, flatBlkDir);
  107.  
  108.   *pflatEntry = BlkDir.flatAddr + DIR_DOTSSIZE;
  109.   flatEnd     = BlkDir.flatAddr + BlkDir.cbSize;
  110.   while (*pflatEntry < flatEnd)
  111.   {
  112.     cbCurName = VMReadUChar (*pflatEntry);
  113.     VMRead (pEntry, *pflatEntry, sizeof(DIRENTRY)-sizeof(pEntry->achName) + cbCurName);
  114.     pEntry->achName[cbCurName] = '\0';
  115.     FSH_UPPERCASE (pEntry->achName, 256, szUpCurName);
  116.  
  117.     rc = memcmp (szUpName, szUpCurName, MIN(cbName,cbCurName));
  118.     if (!rc  &&  cbName == cbCurName)
  119.       return NO_ERROR;
  120.     if (rc < 0)
  121.       return ERROR_FILE_NOT_FOUND;
  122.     *pflatEntry += sizeof(DIRENTRY)-sizeof(pEntry->achName) + cbCurName;
  123.   }
  124.  
  125. #ifdef DEBUG
  126.   if (*pflatEntry != flatEnd)
  127.   {
  128.     debugging = TRUE;
  129.     DEBUG_PRINTF2 ("\r\n!!! UtilScanDir  flatAddr = 0x%08lX   cbSize = 0x%08lX\r\n",
  130.            BlkDir.flatAddr, BlkDir.cbSize);
  131.     INT3;
  132.   }
  133. #endif
  134.  
  135.   return ERROR_FILE_NOT_FOUND;
  136. }
  137.  
  138.  
  139.  
  140.  
  141. int UtilLocate (FLAT _ss *pflatBlkDir, FLAT _ss *pflatEntry, PDIRENTRY pEntry,
  142.         PSZ pszPath)
  143. {
  144.   int cbPath;
  145.   int cbComp;
  146.   unsigned char *pchMatch;
  147.   static char achSeparator[2] = { '\\', '/' };
  148.  
  149.   cbPath = strlen (pszPath);
  150.   while (1)
  151.   {
  152.     pchMatch = pszPath;
  153.     if (FSH_FINDCHAR (2, achSeparator, &pchMatch) == ERROR_CHAR_NOT_FOUND)
  154.       break;
  155.  
  156.     /* not reached the end of the path yet, this path component is a subdir */
  157.     cbComp = (int)pchMatch - (int)pszPath;
  158.     if (UtilScanDir (*pflatBlkDir, pflatEntry, pEntry, pszPath, cbComp))
  159.       return LOC_NOPATH;
  160.     if ((pEntry->fDOSattr & DOSATTR_DIRECTORY) == 0)
  161.       return LOC_NOPATH;
  162.     *pflatBlkDir = *pflatEntry + FIELDOFFSET(DIRENTRY,fblkFile);
  163.     pszPath += cbComp+1;
  164.     cbPath  -= cbComp+1;
  165.   }
  166.  
  167.   /* no more backslashes in pszPath, we have reached the name component */
  168.   cbComp = cbPath;
  169.   if (UtilScanDir (*pflatBlkDir, pflatEntry, pEntry, pszPath, cbComp))
  170.   {
  171.     /* name doesn't exist, let's initialize cbName and achName in case this
  172.        file is about to be created */
  173.     pEntry->cbName = cbComp;
  174.     memcpy (pEntry->achName, pszPath, cbComp+1);
  175.     return LOC_NOENTRY;
  176.   }
  177.  
  178.   if (pEntry->fDOSattr & DOSATTR_DIRECTORY)
  179.     return LOC_DIRENTRY;
  180.   else
  181.     return LOC_FILEENTRY;
  182. }
  183.  
  184.  
  185.  
  186.  
  187. int UtilAttrMatch (USHORT usPattern, USHORT usAttr)
  188. {
  189.   USHORT usMusthave;
  190.   USHORT usMayhave;
  191.  
  192.   usMusthave = usPattern >> 8;
  193.   usMayhave  = usPattern & 0x00FF;
  194.  
  195.   if (usMusthave == 0)
  196.     usMayhave |= (DOSATTR_READONLY | DOSATTR_ARCHIVED);
  197.  
  198.   if (usAttr & ~usMayhave)
  199.     return ERROR_FILE_NOT_FOUND;
  200.  
  201.   if (usMusthave & ~usAttr)
  202.     return ERROR_FILE_NOT_FOUND;
  203.  
  204.   return NO_ERROR;
  205. }
  206.  
  207.  
  208.  
  209.  
  210. int UtilInsertEntry (PVOLUME pVolume, FLAT flatBlkDir, PDIRENTRY pEntry,
  211.              FLAT _ss *pflatEntry)
  212. {
  213.   ULONG cbEntry;
  214.   ULONG ofsEntry;
  215.   ULONG ofsOldBlkEnd;
  216.   BLOCK BlkDir;
  217.  
  218.   VMReadBlk (&BlkDir, flatBlkDir);
  219.  
  220. #ifdef DEBUG
  221.   if (*pflatEntry < BlkDir.flatAddr + DIR_DOTSSIZE  ||
  222.       *pflatEntry > BlkDir.flatAddr + BlkDir.cbSize)
  223.   {
  224.     debugging = TRUE;
  225.     DEBUG_PRINTF3 ("\r\n!!! UtilInsertEntry  0x%08lX <= 0x%08lX <= 0x%08lX\r\n",
  226.            BlkDir.flatAddr + DIR_DOTSSIZE,
  227.            *pflatEntry,
  228.            BlkDir.flatAddr + BlkDir.cbSize);
  229.     INT3;
  230.   }
  231. #endif
  232.  
  233.   ofsEntry = *pflatEntry - BlkDir.flatAddr;
  234.   cbEntry = sizeof(DIRENTRY)-sizeof(pEntry->achName) + pEntry->cbName;
  235.   ofsOldBlkEnd = BlkDir.cbSize;
  236.  
  237.   /* grow the dir block */
  238.   if (BlockReallocDir (pVolume, &BlkDir, BlkDir.cbSize + cbEntry))
  239.     return ERROR_DISK_FULL;
  240.  
  241.   *pflatEntry = BlkDir.flatAddr + ofsEntry;
  242.  
  243.   /* insert the new entry */
  244.   BlockDirCopy (pVolume, BlkDir.flatAddr + ofsEntry + cbEntry,
  245.         BlkDir.flatAddr + ofsEntry, ofsOldBlkEnd - ofsEntry);
  246.   VMWrite (*pflatEntry, pEntry, cbEntry);
  247.   VMWriteBlk (flatBlkDir, &BlkDir);
  248.  
  249.   return NO_ERROR;
  250. }
  251.  
  252.  
  253.  
  254.  
  255. void UtilDeleteEntry (PVOLUME pVolume, FLAT flatBlkDir, PDIRENTRY pEntry,
  256.               FLAT flatEntry)
  257. {
  258.   ULONG cbEntry;
  259.   ULONG ofsEntry;
  260.   ULONG ofsOldBlkEnd;
  261.   FLAT  flatOldBlk;
  262.   BLOCK BlkDir;
  263.  
  264.   VMReadBlk (&BlkDir, flatBlkDir);
  265.  
  266. #ifdef DEBUG
  267.   if (flatEntry <  BlkDir.flatAddr + DIR_DOTSSIZE  ||
  268.       flatEntry >= BlkDir.flatAddr + BlkDir.cbSize)
  269.   {
  270.     debugging = TRUE;
  271.     DEBUG_PRINTF3 ("\r\n!!! UtilDeleteEntry  0x%08lX <= 0x%08lX < 0x%08lX\r\n",
  272.            BlkDir.flatAddr + DIR_DOTSSIZE,
  273.            flatEntry,
  274.            BlkDir.flatAddr + BlkDir.cbSize);
  275.     INT3;
  276.   }
  277. #endif
  278.  
  279.   ofsEntry = flatEntry - BlkDir.flatAddr;
  280.   cbEntry  = sizeof(DIRENTRY)-sizeof(pEntry->achName) + pEntry->cbName;
  281.   flatOldBlk = BlkDir.flatAddr;
  282.   ofsOldBlkEnd = BlkDir.cbSize;
  283.  
  284.   BlockDirCopy (pVolume, flatOldBlk+ofsEntry, flatOldBlk+ofsEntry+cbEntry,
  285.         ofsOldBlkEnd-ofsEntry-cbEntry);
  286.   if (BlockReallocDir (pVolume, &BlkDir, ofsOldBlkEnd-cbEntry))
  287.   {
  288. #ifdef DEBUG
  289.     debugging = TRUE;
  290.     DEBUG_PRINTF0 ("\r\n!!! UtilDeleteEntry  Realloc error too difficult to handle\r\n");
  291. #endif
  292.     INT3;
  293.   }
  294.   VMWriteBlk (flatBlkDir, &BlkDir);
  295. }
  296.  
  297.  
  298.  
  299.  
  300.  
  301. void UtilEnterRamfs (void)
  302. {
  303.   while (InRamfs)
  304.   {
  305.     DEBUG_PRINTF0 ("\r\n\r\n>>> UtilEnterRamfs Conflict\r\n");
  306.  
  307.     /* Sleep for one tick */
  308.     _asm
  309.     {
  310.       mov ax, 0xFEDE
  311.       mov bx, 0xEBBE
  312.       sub di, di
  313.       mov cx, 1
  314.       mov dx, 0x104
  315.     }
  316.     (*DevHlp)();
  317.   }
  318.   InRamfs = TRUE;
  319. }
  320.  
  321.  
  322.  
  323. void UtilExitRamfs (void)
  324. {
  325. #ifdef DEBUG
  326.   if (!InRamfs)
  327.   {
  328.     debugging = TRUE;
  329.     DEBUG_PRINTF0 ("\r\n\a!!! Bad UtilExitRamfs\r\n");
  330.     INT3;
  331.   }
  332. #endif
  333.  
  334.   InRamfs = FALSE;
  335. }
  336.