예제 #1
0
int IFSEXPORT
FS_FINDFROMNAME(
   struct fsfsi far * pfsfsi,
   struct fsfsd far * pfsfsd,
   char far * pData,
   unsigned short cbData,
   unsigned short far * pcMatch,
   unsigned short usLevel,
   unsigned long ulPosition,
   char far * pszName,
   unsigned short fsFlags
   )
{
   int rc;
   struct findfromname far * p = &pRequest->data.findfromname;

   if (rc = requestExchangeXS()) return rc;

   pRequest->rq = FSRQ_FINDFROMNAME;

   COPYPTR(&p->pVolData, queryVPFSD(pfsfsi->fsi_hVPB));
   COPYPTR(&p->pSearchData, pfsfsd);

   p->cbData = cbData;
   p->cMatch = *pcMatch;
   p->usLevel = usLevel;
   p->fsFlags = fsFlags;
   p->ulPosition = ulPosition;

   if (strlen(pszName) >= CCHMAXPATH)
      RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
   strcpy(p->szName, pszName);

   if (usLevel == FIL_QUERYEASFROMLIST) {
      rc = copyEAOP((PEAOP) pData, CEA_GEAS_TO_BUF, 0);
      if (rc) return rc;
      p->cbData -= sizeof(EAOP);
   }

   if (rc = signalDaemonAndWait()) RELEASE_AND_EXIT(rc);

   if (!pRequest->rc || pRequest->rc == ERROR_EAS_DIDNT_FIT) {
      rc = FSH_PROBEBUF(PB_OPWRITE, pData, cbData);
      if (rc) RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
      if (usLevel == FIL_QUERYEASFROMLIST) {
         rc = copyEAOP((PEAOP) pData, CEA_SET_OERROR, p->oError);
         if (rc) RELEASE_AND_EXIT(rc);
         pData += sizeof(EAOP);
         cbData -= sizeof(EAOP);
      }
      memcpy(pData, pFSData, cbData);
   }

   *pcMatch = p->cMatch;

   RELEASE_AND_EXIT(pRequest->rc);
}
예제 #2
0
int IFSEXPORT
FS_FSINFO(
   unsigned short fsFlag,
   unsigned short hVPB,
   char far * pData,
   unsigned short cbData,
   unsigned short usLevel
   )
{
   int rc;
   struct fsinfo far * p = &pRequest->data.fsinfo;

   if (rc = requestExchangeXS()) return rc;

   pRequest->rq = FSRQ_FSINFO;

   p->fsFlag = fsFlag;

   COPYPTR(&p->pVolData, queryVPFSD(hVPB));

   p->cbData = cbData;

   if ((fsFlag == INFO_SET) && cbData) {
      rc = FSH_PROBEBUF(PB_OPREAD, pData, cbData);
      if (rc) RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
      memcpy(pFSData, pData, cbData);
   }

   p->usLevel = usLevel;

   if (rc = signalDaemonAndWait()) RELEASE_AND_EXIT(rc);

   if ((fsFlag == INFO_RETRIEVE) && !pRequest->rc) {
      cbData = p->cbData;
      if (cbData) {
         rc = FSH_PROBEBUF(PB_OPWRITE, pData, cbData);
         if (rc) RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
         memcpy(pData, pFSData, cbData);
      }
   }

   RELEASE_AND_EXIT(pRequest->rc);
}
예제 #3
0
int IFSEXPORT
FS_WRITE(
   struct sffsi far * psffsi,
   struct sffsd far * psffsd,
   char far * pData,
   unsigned short far * pcbLen,
   unsigned short fsIOFlag
   )
{
   int rc;
   struct write far * p = &pRequest->data.write;

   if (rc = requestExchangeXS()) return rc;

   pRequest->rq = FSRQ_WRITE;

   COPYPTR(&p->pVolData, queryVPFSD(psffsi->sfi_hVPB));

   p->sffsi = *psffsi;
   COPYPTR(&p->pOpenFileData, psffsd);

   p->cbLen = *pcbLen;
   p->fsIOFlag = fsIOFlag;

   if (*pcbLen) {
      rc = FSH_PROBEBUF(PB_OPREAD, pData, *pcbLen);
      if (rc) RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
      memcpy(pFSData, pData, *pcbLen);
   }

   if (rc = signalDaemonAndWait()) RELEASE_AND_EXIT(rc);

   *psffsi = p->sffsi;
   
   *pcbLen = p->cbLen;
   
   RELEASE_AND_EXIT(pRequest->rc);
}
예제 #4
0
int     far pascal _loadds FS_FINDFIRST(
                               struct cdfsi   far *pcdfsi,
                               struct cdfsd   far *pcdfsd,
                               char           far *pName,
                               unsigned short iCurDirEnd,
                               unsigned short attr,
                               struct fsfsi   far *pfsfsi,
                               struct fsfsd   far *pfsfsd,
                               char           far *pData,
                               unsigned short cbData,
                               unsigned short far *pcMatch,
                               unsigned short level,
                               unsigned short flags
                              )
{
  int    rc;
  unsigned long size;
  char far *p;
  FILEFINDBUF2 far *ff;
  char buf[0x100];

  kprintf("**** FS_FINDFIRST(\"%s\"), level=%u, flags=%u, curdir=%s, iCurDirEnd=%d\n",
          pName, level, flags, pcdfsi->cdi_curdir, iCurDirEnd);

  p = pName;
  // skip a drive letter
  if (p[1] == ':' && p[2] == '\\') p += 2;

  /* find by trying to open */
  *pcMatch = 0; rc = 2; // file not found
  if (!MFS_OPEN(p, &size))
  {
    // file found
    switch (level)
    {
    case 1:
      *pcMatch = 1;
      break;
    case 2: // query EA size, specially for *.cmd
      // query write access to the buffer
      if (!FSH_PROBEBUF(1, pData, cbData))
      {
        // fill in the position field
        *((unsigned long far *)pData) = 0; // sizeof(FILEFINDBUF2) - CCHMAXPATHCOMP;
        pData += sizeof(unsigned long);
        ff = (FILEFINDBUF2 far *)pData;
        ff->cbFile = size;
        ff->cbFileAlloc = size;
        ff->cbList = 0; // sizeof(unsigned long);

        // for files in root dir. or files in first-level dirs, return the
        // full pathname; for deeper files, return a filename with last dir
        // i.e.: s:\tools\netdrive\ndctl.exe -> netdrive\ndctl.exe
        for (p = pName + strlen(pName) - 1; p > pName && *p != '\\'; p--) ;
        if (p - pName > 2)
        {
          p--;
          for (; p > pName && *p != '\\'; p--) ;
        }
        if (p - pName > 2)
          p++;
        else
          p = pName;

        ff->cchName = strlen(p);
        if (attr & 0x0040)
        {
          strcpy(ff->achName, p);
          attr &= ~0x0040;
        }
        else
          FSH_UPPERCASE(p, ff->cchName, ff->achName);

        kprintf("achName=%s, curdir=%s, cdi_end=%d\n", ff->achName, pcdfsi->cdi_curdir, pcdfsi->cdi_end);
      }
      else
        kprintf("FSH_PROBEBUF failed!\n");
      break;
    default:
      break;
    }

    rc = 0;
  }

  return rc;
}
예제 #5
0
int far pascal _loadds FS_READ(
                          struct sffsi   far *psffsi,
                          struct sffsd   far *psffsd,
                          char           far *pData,
                          unsigned short far *pLen,
                          unsigned short     IOflag
                         )
{
  int rc;

  kprintf("**** FS_READ\n");

  filemax = psffsi->sfi_size;
  filepos = psffsi->sfi_position;

  kprintf("sfi_size = %lu, sfi_position = %lu\n", filemax, filepos);
  kprintf("buf = 0x%08lx, size = %u\n", pData, *pLen);

  if (*((unsigned long far *)psffsd + 1)) // direct read flag
  {
    if (!(rc = FSH_PROBEBUF(1, pData, *pLen)))
    {
      unsigned short cbSec = *pLen / secsize;
      if (rc = FSH_DOVOLIO(8,                    // return errors directly, don't use harderr daemon
                           1 + 2 + 4,            // ABORT | RETRY | FAIL
                           psffsi->sfi_hVPB,
                           pData,
                           &cbSec,
                           filepos / secsize))
        kprintf("FSH_DOVOLIO failed, rc = %u\n", rc);
      else
      {
        kprintf("FSH_DOVOLIO(buf = 0x%08lx, len = %u, start = %lu sectors) succeeded\n",
                pData,
                cbSec,
                filepos / secsize);
        *pLen = cbSec * secsize;
        kprintf("%u butes read\n", *pLen);
        filepos += *pLen;
        rc = NO_ERROR;
      }
    }
    else
    {
      kprintf("FS_READ: FSH_PROBEBUF failed!\n");
      rc = 1;
    }
  }
  else
  {
    filebase = *((unsigned long far *)psffsd);
    advance_ptr();
    if (rc = MFS_READ(pData, pLen))
    {
      kprintf("MFS_READ failed, rc = %u\n", rc);
    }
  }
  psffsi->sfi_position = filepos;

  return rc;
}
예제 #6
0
static APIRET copyEAOP(PEAOP pEABuf, USHORT usWhat, USHORT oError)
{
   APIRET rc, rcfinal = NO_ERROR;
   PFEALIST pfeas;
   PGEALIST pgeas;
   ULONG cbList;
   
   /* Is the EAOP structure readable? */
   rc = FSH_PROBEBUF(PB_OPREAD, (char far *) pEABuf, sizeof(EAOP));
   if (rc) return ERROR_INVALID_PARAMETER;

   pfeas = pEABuf->fpFEAList;
   pgeas = pEABuf->fpGEAList;

   /* Set the error code? */
   if (usWhat & CEA_SET_OERROR) {

      /* Is the EAOP structure writeable? */
      rc = FSH_PROBEBUF(PB_OPWRITE, (char far *) pEABuf, sizeof(EAOP));
      if (rc) return ERROR_INVALID_PARAMETER;

      pEABuf->oError = oError;
   }

   if ((usWhat & CEA_FEAS_TO_BUF) ||
       (usWhat & CEA_BUF_TO_FEAS))
   {
      /* Can we read the FEA list's cbList member? */
      rc = FSH_PROBEBUF(PB_OPREAD, (char far *) pfeas, sizeof(ULONG));
      if (rc) return ERROR_INVALID_PARAMETER;

      /* Copy FEAs to the data exchange buffer? */
      if (usWhat & CEA_FEAS_TO_BUF) {
         
         /* Is cbList not too small or too big? */
         if (pfeas->cbList < 4) return ERROR_EA_LIST_INCONSISTENT;
         if (pfeas->cbList > 65536) return ERROR_EA_LIST_TOO_LONG;
         
         /* Can we read the entire FEA list? */
         rc = FSH_PROBEBUF(PB_OPREAD, (char far *) pfeas,
            (USHORT) pfeas->cbList);
         if (rc) return ERROR_INVALID_PARAMETER;
         
         /* OK, copy the FEA list. */
         memcpy(pFSData, pfeas, pfeas->cbList);
      }
      
      /* Copy data exchange buffer to the FEA buffer? */
      if (usWhat & CEA_BUF_TO_FEAS) {
         
         cbList = ((PFEALIST) pFSData)->cbList;

         /* Is the FEA buffer big enough?  In not, we copy as much as
            possible and return an overflow error. */
         if ((cbList > 65536) ||
             (cbList > pfeas->cbList)) {
            rcfinal = ERROR_BUFFER_OVERFLOW;
            cbList = pfeas->cbList;
         }

         /* Can we write the entire FEA list? */
         rc = FSH_PROBEBUF(PB_OPWRITE, (char far *) pfeas,
            (USHORT) cbList);
         if (rc) return ERROR_INVALID_PARAMETER;
         
         /* OK, copy the FEA list. */
         memcpy(pfeas, pFSData, cbList);
      }
      
   }

   /* Copy GEAs to the data exchange buffer? */
   if (usWhat & CEA_GEAS_TO_BUF) {
      
      /* Can we read the GEA list's cbList member? */
      rc = FSH_PROBEBUF(PB_OPREAD, (char far *) pgeas, sizeof(ULONG));
      if (rc) return ERROR_INVALID_PARAMETER;

      /* Is cbList not too small or too big? */
      if (pgeas->cbList < 4) return ERROR_EA_LIST_INCONSISTENT;
      if (pgeas->cbList > 65536) return ERROR_EA_LIST_TOO_LONG;
         
      /* Can we read the entire GEA list? */
      rc = FSH_PROBEBUF(PB_OPREAD, (char far *) pgeas,
         (USHORT) pgeas->cbList);
      if (rc) return ERROR_INVALID_PARAMETER;
         
      /* OK, copy the FEA list. */
      memcpy(pFSData, pgeas, pgeas->cbList);
   }
      
   return rc;
}
예제 #7
0
int IFSEXPORT
FS_IOCTL(
   struct sffsi far * psffsi,
   struct sffsd far * psffsd,
   unsigned short usCat,
   unsigned short usFunc,
   char far * pParm,
   unsigned short cbMaxParm,
   unsigned short far * pcbParm,
   char far * pData,
   unsigned short cbMaxData,
   unsigned short far * pcbData
   )
{
   int rc;
   struct ioctl far * p = &pRequest->data.ioctl;

   if (rc = requestExchangeXS()) return rc;

   pRequest->rq = FSRQ_IOCTL;

   COPYPTR(&p->pVolData, queryVPFSD(psffsi->sfi_hVPB));
   
   p->sffsi = *psffsi;
   COPYPTR(&p->pOpenFileData, psffsd);
   
   p->usCat = usCat;
   p->usFunc = usFunc;
   p->cbParm = cbMaxParm ? *pcbParm : 0;
   p->cbMaxData = cbMaxData;
   p->cbData = 0;

   /* Validate the parameter buffer. */
   if (cbMaxParm) {
      rc = FSH_PROBEBUF(PB_OPREAD, (char far *) pcbParm,
         sizeof(USHORT));
      if (rc) return ERROR_INVALID_PARAMETER;
      if (*pcbParm > cbMaxParm) return ERROR_INVALID_PARAMETER;
      if (*pcbParm) {
         rc = FSH_PROBEBUF(PB_OPREAD, pParm, *pcbParm);
         if (rc) return ERROR_INVALID_PARAMETER;
      }
      memcpy(pFSData, pParm, *pcbParm);
   }

   if (rc = signalDaemonAndWait()) RELEASE_AND_EXIT(rc);

   if (p->cbData) {
      rc = FSH_PROBEBUF(PB_OPWRITE, (char far *) pcbData,
         sizeof(USHORT));
      if (rc) RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
      *pcbData = p->cbData;
      if (!pRequest->rc) {
         if (*pcbData > cbMaxData)
            RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
         if (*pcbData) {
            rc = FSH_PROBEBUF(PB_OPWRITE, pData, *pcbData);
            if (rc) RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
            memcpy(pData, pFSData, *pcbData);
         }
      }
   }
         
   RELEASE_AND_EXIT(pRequest->rc);
}
예제 #8
0
int IFSEXPORT
FS_FSCTL(
   union argdat far * pArgDat,
   unsigned short iArgType,
   unsigned short usFunc,
   char far * pParm,
   unsigned short cbMaxParm,
   unsigned short far * pcbParm,
   char far * pData,
   unsigned short cbMaxData,
   unsigned short far * pcbData
   )
{
   int rc;
   struct fsctl far * p = &pRequest->data.fsctl;

   /* Validate iArgType. */
   if ((iArgType != FSCTL_ARG_FILEINSTANCE) &&
       (iArgType != FSCTL_ARG_CURDIR) &&
       (iArgType != FSCTL_ARG_NULL))
      return ERROR_NOT_SUPPORTED;

   /* Validate the parameter buffer. */
   if (cbMaxParm) {
      rc = FSH_PROBEBUF(PB_OPREAD, (char far *) pcbParm,
         sizeof(USHORT));
      if (rc) return ERROR_INVALID_PARAMETER;
      if (*pcbParm > cbMaxParm) return ERROR_INVALID_PARAMETER;
      if (*pcbParm) {
         rc = FSH_PROBEBUF(PB_OPREAD, pParm, *pcbParm);
         if (rc) return ERROR_INVALID_PARAMETER;
      }
   }

   switch (usFunc) {

      case FSCTL_STUBFSD_DAEMON_STARTED: /* daemon started */
      
         if (pidDaemon) return ERROR_STUBFSD_DAEMON_RUNNING;

         if (*pcbParm != sizeof(SETXCHGBUFFERS))
            return ERROR_INVALID_PARAMETER;

         return daemonStarted((PSETXCHGBUFFERS) pParm);

      case FSCTL_STUBFSD_DAEMON_STOPPED: /* daemon stopped */
      
         if (!pidDaemon)
            return ERROR_STUBFSD_DAEMON_NOT_RUN;

         if (queryCurrentPid() != pidDaemon)
            return ERROR_STUBFSD_NOT_DAEMON;

         return daemonStopped();

      case FSCTL_STUBFSD_RESET: /* forcibly detach daemon */
      
         return daemonStopped();

      case FSCTL_STUBFSD_GET_REQUEST: /* wait for next request */

         if (queryCurrentPid() != pidDaemon)
            return ERROR_STUBFSD_NOT_DAEMON;

         rc = FSH_SEMWAIT(&semRqAvail, TO_INFINITE);
         if (rc) return rc;
         
         rc = FSH_SEMSET(&semRqAvail);
         if (rc) return rc;

         return NO_ERROR;

      case FSCTL_STUBFSD_DONE_REQUEST: /* signal request done */
      
         if (queryCurrentPid() != pidDaemon)
            return ERROR_STUBFSD_NOT_DAEMON;

         rc = FSH_SEMCLEAR(&semRqDone);
         if (rc) return rc;

         return NO_ERROR;

      default: /* unknown FSCTL, send to daemon */

         if (rc = requestExchangeXS()) return rc;

         pRequest->rq = FSRQ_FSCTL;

         p->iArgType = iArgType;
         p->usFunc = usFunc;
         p->cbParm = cbMaxParm ? *pcbParm : 0;
         p->cbMaxData = cbMaxData;
         p->cbData = 0;

         if (cbMaxParm) memcpy(pFSData, pParm, *pcbParm);

         if (rc = signalDaemonAndWait()) RELEASE_AND_EXIT(rc);

         if (p->cbData) {
            rc = FSH_PROBEBUF(PB_OPWRITE, (char far *) pcbData,
               sizeof(USHORT));
            if (rc) RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
            *pcbData = p->cbData;
            if (!pRequest->rc) {
               if (*pcbData > cbMaxData)
                  RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
               if (*pcbData) {
                  rc = FSH_PROBEBUF(PB_OPWRITE, pData, *pcbData);
                  if (rc) RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
                  memcpy(pData, pFSData, *pcbData);
               }
            }
         }
         
         RELEASE_AND_EXIT(pRequest->rc);
   }

}
예제 #9
0
int IFSEXPORT
FS_FINDFIRST(
   struct cdfsi far * pcdfsi,
   struct cdfsd far * pcdfsd,
   char far * pszName,
   unsigned short iCurDirEnd,
   unsigned short fsAttr,
   struct fsfsi far * pfsfsi,
   struct fsfsd far * pfsfsd,
   char far * pData,
   unsigned short cbData,
   unsigned short far * pcMatch,
   unsigned short usLevel,
   unsigned short fsFlags
   )
{
   int rc, rc2;
   struct findfirst far * p = &pRequest->data.findfirst;

   if (rc = requestExchangeXS()) return rc;

   pRequest->rq = FSRQ_FINDFIRST;

   COPYPTR(&p->pVolData, queryVPFSD(pcdfsi->cdi_hVPB));
   p->cdfsi = *pcdfsi;
   p->cdfsd = *pcdfsd;

   if (strlen(pszName) >= CCHMAXPATH)
      RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
   strcpy(p->szName, pszName);
   p->iCurDirEnd = iCurDirEnd;

   p->fsAttr = fsAttr;
   p->cbData = cbData;
   p->cMatch = *pcMatch;
   p->usLevel = usLevel;
   p->fsFlags = fsFlags;

   if (usLevel == FIL_QUERYEASFROMLIST) {
      rc = copyEAOP((PEAOP) pData, CEA_GEAS_TO_BUF, 0);
      if (rc) return rc;
      p->cbData -= sizeof(EAOP);
   }

   if (rc = signalDaemonAndWait()) RELEASE_AND_EXIT(rc);

   if (!pRequest->rc || pRequest->rc == ERROR_EAS_DIDNT_FIT) {
      rc = FSH_PROBEBUF(PB_OPWRITE, pData, cbData);
      if (rc) {
         rc2 = undoFindFirst(pcdfsi);
         if (rc2) RELEASE_AND_EXIT(rc2);
         RELEASE_AND_EXIT(ERROR_INVALID_PARAMETER);
      }
      if (usLevel == FIL_QUERYEASFROMLIST) {
         rc = copyEAOP((PEAOP) pData, CEA_SET_OERROR, p->oError);
         if (rc) {
            rc2 = undoFindFirst(pcdfsi);
            if (rc2) RELEASE_AND_EXIT(rc2);
            RELEASE_AND_EXIT(rc);
         }
         pData += sizeof(EAOP);
         cbData -= sizeof(EAOP);
      }
      memcpy(pData, pFSData, cbData);
   }

   COPYPTR(pfsfsd, &p->pSearchData);

   *pcMatch = p->cMatch;
      
   RELEASE_AND_EXIT(pRequest->rc);
}