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); }
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); }
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); }
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; }
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; }
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; }
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); }
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); } }
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); }