Пример #1
0
CoreResult coreQueryDirEntries(CryptedVolume * pVolume,
   CryptedFileID id, CryptedDirEntry * * ppEntries)
{
   CoreResult cr, crread;
   CryptedFileInfo info;
   CryptedFilePos cbRead;
   octet * pabBuffer;
   
   *ppEntries = 0;

   /* Get file info. */
   cr = coreQueryFileInfo(pVolume, id, &info);
   if (cr) return cr;

   if (!CFF_ISDIR(info.flFlags)) return CORERC_NOT_DIRECTORY;

   if (!info.cbFileSize) return CORERC_OK;
   
   /* Allocate memory for the encoded directory data. */
   pabBuffer = sysAllocSecureMem(info.cbFileSize);
   if (!pabBuffer)
      return CORERC_NOT_ENOUGH_MEMORY;
   
   /* Read the directory.  Continue even if an error occurs, because
      part of the directory might still be readable. */
   crread = coreReadFromFile(pVolume, id, 0,
      info.cbFileSize, pabBuffer, &cbRead);

   /* Decode the directory data. */
   cr = decodeDir(cbRead, pabBuffer, ppEntries);
   sysFreeSecureMem(pabBuffer);
   return crread ? crread : cr;
}
Пример #2
0
/* Set the archived bit and the last write time. */
APIRET easChanged(CryptedVolume * pVolume, CryptedFileID idFile,
   bool fHidden, struct sffsi * psffsi)
{
   CoreResult cr;
   CryptedFileInfo info;
   
   cr = coreQueryFileInfo(pVolume, idFile, &info);
   if (cr) return coreResultToOS2(cr);
   
   info.flFlags |= CFF_OS2A;
   info.timeWrite = curTime();

   if (psffsi) {
      psffsi->sfi_tstamp = (psffsi->sfi_tstamp | ST_PWRITE) &
         ~ST_SWRITE;
      coreToSffsi(fHidden, &info, psffsi);
   }

   return coreResultToOS2(coreSetFileInfo(pVolume, idFile, &info));
}
Пример #3
0
APIRET setLevel1Info(CryptedVolume * pVolume, struct sffsi * psffsi,
   CryptedFileID idFile, CryptedFileID idDir, bool fHidden,
   PFILESTATUS pStat)
{
   CoreResult cr;
   APIRET rc;
   CryptedFileInfo info;

   cr = coreQueryFileInfo(pVolume, idFile, &info);
   if (cr) return coreResultToOS2(cr);

   if (!beq(CFF_ISDIR(info.flFlags),
      pStat->attrFile & FILE_DIRECTORY))
      return ERROR_INVALID_PARAMETER;

   if (rc = doTimeChange(* (ULONG *) &pStat->fdateCreation,
      &info.timeCreation, psffsi, ST_SCREAT)) return rc;
   if (rc = doTimeChange(* (ULONG *) &pStat->fdateLastAccess,
      &info.timeAccess, psffsi, ST_SREAD)) return rc;
   if (rc = doTimeChange(* (ULONG *) &pStat->fdateLastWrite,
      &info.timeWrite, psffsi, ST_SWRITE)) return rc;
   
   extractDOSAttr(pStat->attrFile, &info);

   cr = coreSetFileInfo(pVolume, idFile, &info);
   if (cr) return coreResultToOS2(cr);

   if (!beq(fHidden, pStat->attrFile & FILE_HIDDEN)) {
      fHidden = pStat->attrFile & FILE_HIDDEN;
      cr = setHiddenFlag(pVolume, idDir, idFile, fHidden);
      if (cr) return coreResultToOS2(cr);
   }
   
   if (psffsi) coreToSffsi(fHidden, &info, psffsi);
   
   return NO_ERROR;
}
Пример #4
0
static APIRET changeDir(ServerData * pServerData,
   struct chdir * pchdir)
{
   CoreResult cr;
   VolData * pVolData;
   CryptedVolume * pVolume;
   CryptedFileID idDir;
   CryptedFileInfo info;
   
   if (VERIFYFIXED(pchdir->szDir) ||
       verifyPathName(pchdir->szDir))
      return ERROR_INVALID_PARAMETER;
   
   GET_VOLUME(pchdir);
   pVolume = pVolData->pVolume;
   
   logMsg(L_DBG, "CD_EXPLICIT, newdir=%s", pchdir->szDir);

   cr = findFromCurDir2(pVolData, pchdir->szDir, &pchdir->cdfsi,
       &pchdir->cdfsd, pchdir->iCurDirEnd, &idDir, 0);
   if (cr) return coreResultToOS2(cr);

   /* Get info */
   cr = coreQueryFileInfo(pVolume, idDir, &info);
   if (cr) return coreResultToOS2(cr);

   /* Is this really a directory? */
   if (!CFF_ISDIR(info.flFlags))
      /* This error code is not entirely concise, but it's what OS/2
         wants to see. */
      return ERROR_PATH_NOT_FOUND;

   pchdir->cdfsd.data[0] = idDir;
   
   return NO_ERROR;
}
Пример #5
0
APIRET fsFileAttribute(ServerData * pServerData,
   struct fileattribute * pfileattribute)
{
   CoreResult cr;
   VolData * pVolData;
   CryptedVolume * pVolume;
   CHAR szName[CCHMAXPATH];
   CryptedFileID idDir;
   CryptedFileID idFile;
   CryptedFileInfo info, info2;
   CryptedDirEntry * pDirEntry;
   bool fHidden;
   
   if (VERIFYFIXED(pfileattribute->szName) ||
       verifyPathName(pfileattribute->szName))
      return ERROR_INVALID_PARAMETER;
   
   GET_VOLUME(pfileattribute);
   pVolume = pVolData->pVolume;
   
   logMsg(L_DBG,
      "FS_FILEATTRIBUTE, szName=%s, fsFlag=%hd, fsAttr=%hd",
      pfileattribute->szName, pfileattribute->fsFlag,
      pfileattribute->fsAttr);
   
   cr = findFromCurDir(pVolData, pfileattribute->szName,
       &pfileattribute->cdfsi, &pfileattribute->cdfsd,
       pfileattribute->iCurDirEnd, &idDir, &idFile, &pDirEntry,
       szName);
   if (cr) return coreResultToOS2(cr);

   fHidden = pDirEntry->flFlags & CDF_HIDDEN;
   coreFreeDirEntries(pDirEntry);
   
   /* Access the file and get file info. */
   cr = coreQueryFileInfo(pVolume, idFile, &info);
   if (cr) return coreResultToOS2(cr);

   if (pfileattribute->fsFlag & FA_SET) {
      
      /* Set the file attributes. */
      
      /* Update the hidden flag in the directory, if necessary. */
      if (!beq(fHidden, pfileattribute->fsAttr & FILE_HIDDEN)) {
         cr = setHiddenFlag(pVolume, idDir, idFile,
            pfileattribute->fsAttr & FILE_HIDDEN);
         if (cr) return coreResultToOS2(cr);
      }

      /* Update the flags in the info sector, if necessary. */
      info2 = info;
      extractDOSAttr(pfileattribute->fsAttr, &info2);

      if (info2.flFlags != info.flFlags) {
         cr = coreSetFileInfo(pVolume, idFile, &info2);
         if (cr) return coreResultToOS2(cr);
      }

      return NO_ERROR;
      
   } else {
      /* Query the file attributes. */
      pfileattribute->fsAttr = makeDOSAttr(fHidden, &info);
      return NO_ERROR;
   }
}
Пример #6
0
APIRET doFileInfo(struct sffsi * psffsi,
   ULONG flFlag, ULONG ulLevel,
   VolData * pVolData, CryptedFileID idFile,
   CryptedFileID idDir, bool fHidden,
   ULONG cbData, char * pData)
{
   CoreResult cr;
   APIRET rc;
   CryptedVolume * pVolume = pVolData->pVolume;
   CryptedFileInfo info;
   PGEALIST pgeas;
   
   /* Access the file and get file info. */
   cr = coreQueryFileInfo(pVolume, idFile, &info);
   if (cr) return coreResultToOS2(cr);

   if (flFlag & FI_SET) {

      /* Set file info. */

      switch (ulLevel) {

         case FIL_STANDARD: /* Set file info. */

            if (cbData < sizeof(FILESTATUS))
               return ERROR_INVALID_PARAMETER;
            return setLevel1Info(pVolume, psffsi, idFile, idDir,
               fHidden, (PFILESTATUS) pData);

         case FIL_QUERYEASIZE: /* Set EAs. */

            rc = addEAs(pVolume, idFile, (PFEALIST) pData);
            if (rc) return rc;
            return easChanged(pVolume, idFile, fHidden, psffsi);
            
         default:
            logMsg(L_EVIL,
               "unknown set-FS_[FILE|PATH]INFO info level: %d",
               ulLevel);
            return ERROR_NOT_SUPPORTED;
      }
      
   } else {

      /* Query file info. */

      switch (ulLevel) {

         case FIL_STANDARD:     
         case FIL_QUERYEASIZE: /* Query level 1 or 2 file info. */
            
            memset(pData, 0, cbData);
            return storeFileInfo(0, 0, 0, 0,
               fHidden,
               &info,
               &pData,
               &cbData,
               ulLevel,
               0, 0);

         case FIL_QUERYEASFROMLIST: /* Query level 3 (EA) file info. */

            /* The GEAs are stored in the exchange buffer which is
               about to be overwritten; so make a copy. */
            pgeas = alloca(((PGEALIST) pData)->cbList);
            memcpy(pgeas, pData, ((PGEALIST) pData)->cbList);
            
            return storeEAsInFEAList(pVolume, idFile,
               &info, pgeas, 65536, pData);

         case 4: /* Store the entire EA set. */

            return storeEAsInFEAList(pVolume, idFile,
               &info, 0, 65536, pData);

         default:
            logMsg(L_EVIL,
               "unknown query-FS_[FILE|PATH]INFO info level: %d",
               ulLevel);
            return ERROR_NOT_SUPPORTED;
      }
   }
}
Пример #7
0
/* Update file time stamps if required.  Flush none, some or all of
   the file to disk. */
APIRET stampFileAndFlush(VolData * pVolData, CryptedFileID idFile,
   struct sffsi * psffsi, int flush)
{
   CoreResult cr;
   CryptedVolume * pVolume = pVolData->pVolume;
   CryptedFileInfo info;

   /* If any of the ST_Sxxx stamp bits is set, copy the sffsi times
      into the info sector. */
   if (!pVolData->fReadOnly &&
       ((psffsi->sfi_tstamp & (ST_SCREAT | ST_SWRITE)) ||
        ((psffsi->sfi_tstamp & ST_SREAD) &&
         !pVolData->pServerData->fLazyLastAccess)))
   {
      cr = coreQueryFileInfo(pVolume, idFile, &info);
      if (cr) return coreResultToOS2(cr);

      /* Copy the time stamps from the sffsi. */
      os2TimeToCore(
         * (FDATE *) &psffsi->sfi_cdate,
         * (FTIME *) &psffsi->sfi_ctime,
         &info.timeCreation);
      os2TimeToCore(
         * (FDATE *) &psffsi->sfi_adate,
         * (FTIME *) &psffsi->sfi_atime,
         &info.timeAccess);
      os2TimeToCore(
         * (FDATE *) &psffsi->sfi_mdate,
         * (FTIME *) &psffsi->sfi_mtime,
         &info.timeWrite);

      if (psffsi->sfi_tstamp & ST_SWRITE)
         info.flFlags |= CFF_OS2A;

      /* Write the info sector. */
      cr = coreSetFileInfo(pVolume, idFile, &info);
      if (cr) return coreResultToOS2(cr);
   }

   psffsi->sfi_tstamp = 0;

   switch (flush) {

      case SFAF_NOFLUSH:
         break;

      case SFAF_FLUSHINFO:
         /* Flush the info sector if it's in the cache and dirty. */
         cr = coreFlushSector(pVolume, INFOSECTORFILE_ID,
            coreQueryInfoSectorNumber(pVolume, idFile));
         if (cr) return coreResultToOS2(cr);
         break;
         
      case SFAF_FLUSHALL:
         if (cr = coreFlushFile(pVolume, idFile))
            return coreResultToOS2(cr);
         break;

      default:
         abort();
   }

   return NO_ERROR;
}