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; }
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; }
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; }
APIRET storeFileInfo( CryptedVolume * pVolume, /* DosFindXXX level 3 only */ CryptedFileID idFile, /* DosFindXXX level 3 only */ PGEALIST pgeas, /* DosFindXXX level 3 only */ char * pszFileName, /* DosFindXXX only */ bool fHidden, CryptedFileInfo * pInfo, char * * ppData, ULONG * pcbData, ULONG ulLevel, ULONG flFlags, int iNext) { APIRET rc, finalrc = NO_ERROR; PFILESTATUS pBuf; int c; /* This information allows the search to continue from a specific file (for FS_FINDFROMNAME). */ if (flFlags & FF_GETPOS) { if (*pcbData < sizeof(ULONG)) return ERROR_BUFFER_OVERFLOW; * (PULONG) *ppData = iNext; *ppData += sizeof(ULONG); *pcbData -= sizeof(ULONG); } /* Store the level 1 file info. */ if (*pcbData < sizeof(FILESTATUS)) return ERROR_BUFFER_OVERFLOW; pBuf = (PFILESTATUS) *ppData; coreTimeToOS2(pInfo->timeCreation, &pBuf->fdateCreation, &pBuf->ftimeCreation); coreTimeToOS2(pInfo->timeAccess, &pBuf->fdateLastAccess, &pBuf->ftimeLastAccess); coreTimeToOS2(pInfo->timeWrite, &pBuf->fdateLastWrite, &pBuf->ftimeLastWrite); if (CFF_ISDIR(pInfo->flFlags)) { pBuf->cbFile = 0; pBuf->cbFileAlloc = 0; } else { pBuf->cbFile = pInfo->cbFileSize; pBuf->cbFileAlloc = (pInfo->csSet + 1) * SECTOR_SIZE; } pBuf->attrFile = makeDOSAttr(fHidden, pInfo); *ppData += sizeof(FILESTATUS); *pcbData -= sizeof(FILESTATUS); /* Store the requested or all EAs for FS_FINDXXX level 3 and FS_PATH/FILEINFO levels 3 and 4. */ if (ulLevel == FIL_QUERYEASFROMLIST) { rc = storeEAsInFEAList(pVolume, idFile, pInfo, pgeas, *pcbData, *ppData); if (rc == ERROR_BUFFER_OVERFLOW) { /* If the EAs don't fit, try to store level 2 info. If that works, return ERROR_EAS_DIDNT_FIT. However, if that doesn't fit either, return ERROR_BUFFER_OVERFLOW (see below). */ ulLevel = FIL_QUERYEASIZE; finalrc = ERROR_EAS_DIDNT_FIT; } else { if (rc) return rc; *pcbData -= ((PFEALIST) *ppData)->cbList; *ppData += ((PFEALIST) *ppData)->cbList; } } /* Store the size of the EA set on disk for level 2. */ if (ulLevel == FIL_QUERYEASIZE) { if (*pcbData < sizeof(ULONG)) return ERROR_BUFFER_OVERFLOW; * (PULONG) *ppData = pInfo->cbEAs ? pInfo->cbEAs + 2 : 0; *ppData += sizeof(ULONG); *pcbData -= sizeof(ULONG); } /* Store the file name, if one was given (for FS_FINDXXX). */ if (pszFileName) { c = strlen(pszFileName); if (c > 255) return ERROR_FILENAME_EXCED_RANGE; if (*pcbData < c + 2) return ERROR_BUFFER_OVERFLOW; * (PUCHAR) *ppData = c; memcpy(*ppData + 1, pszFileName, c + 1); *ppData += c + 2; *pcbData -= c + 2; } return finalrc; }