📄 wrudf-desc.c
字号:
/* wrudf-desc.c * * PURPOSE * Routines to create/find/insert/delete FileIdentDesc's and FileEntries. * * CONTACTS * E-mail regarding this program to * e.fennema@dataweb.nl * * COPYRIGHT * This file is distributed under the terms of the GNU General Public * License (GPL). Copies of the GPL can be obtained from: * ftp://prep.ai.mit.edu/pub/gnu/GPL * * (C) 2001 Enno Fennema * * HISTORY * 16 Aug 01 ef Created. */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include "wrudf.h"/* removeFID() * * Physically remove a FileIdentDesc from the directory */intremoveFID(Directory *dir, struct fileIdentDesc *fid) { uint32_t lenFID = (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3; uint32_t lenMove; dir->fe.informationLength -= lenFID; lenMove = dir->fe.informationLength - ((uint8_t*)fid - dir->data); memcpy(fid, (uint8_t*)fid + lenFID, lenMove); dir->dirDirty = 1; return 0;}/* deleteFID() * * Remove an FID from the directory * If fileLinkCount now zero, deallocate FileEntry and any data extents */int deleteFID(Directory * dir, struct fileIdentDesc * fid){ int rv; struct fileEntry *fe; rv = CMND_OK;// if( fid->icb.extLocation.partitionReferenceNum != pd->partitionNumber )// return NOT_IN_RW_PARTITION; fe = readTaggedBlock(fid->icb.extLocation.logicalBlockNum, fid->icb.extLocation.partitionReferenceNum); /* check permission */ freeBlock(fid->icb.extLocation.logicalBlockNum, fid->icb.extLocation.partitionReferenceNum); if( fe->fileLinkCount > 1 ) { fe->fileLinkCount--; setChecksum(fe); if( medium == CDRW ) dirtyBlock(fid->icb.extLocation.logicalBlockNum, fid->icb.extLocation.partitionReferenceNum); else vat[fid->icb.extLocation.logicalBlockNum] = writeCDR(fe); } else { if( medium == CDR ) { if( fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY ) dir->fe.fileLinkCount--; vat[fid->icb.extLocation.logicalBlockNum] = 0xFFFFFFFF; } else { if( fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY ) { dir->fe.fileLinkCount--; ((struct logicalVolIntegrityDescImpUse*) (lvid->impUse + 2 * sizeof(uint32_t) * lvid->numOfPartitions))->numDirs--; } else { ((struct logicalVolIntegrityDescImpUse*) (lvid->impUse + 2 * sizeof(uint32_t) * lvid->numOfPartitions))->numFiles--; } /* free file data */ switch( fe->icbTag.flags & ICBTAG_FLAG_AD_MASK ) { case ICBTAG_FLAG_AD_IN_ICB: break; case ICBTAG_FLAG_AD_SHORT: freeShortExtents((short_ad*)(fe->allocDescs + fe->lengthExtendedAttr)); break; case ICBTAG_FLAG_AD_LONG: freeLongExtents((long_ad*)(fe->allocDescs + fe->lengthExtendedAttr)); break; default: printf("UDF does not use Extended Alloc Descs\n"); rv = CMND_FAILED; } /* free the File Entry itself */ markBlock(FREE, fid->icb.extLocation.logicalBlockNum); } } removeFID(dir, fid); dir->dirDirty = 1; return rv;}struct fileIdentDesc* findFileIdentDesc(Directory *dir, char* name) { int i; uint8_t *data; struct fileIdentDesc *fid; char uName[256]; int uLen; uLen = encode_utf8(uName, "", name, 256); data = dir->data; for( i = 0; i < dir->fe.informationLength; i += (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3 ) { fid = (struct fileIdentDesc*)(data + i); if( fid->descTag.tagIdent == TAG_IDENT_TE ) return NULL; if( fid->descTag.tagIdent == TAG_IDENT_IE ) { printf("Indirect Entry not yet implemented\n"); continue; } if( fid->descTag.tagIdent != TAG_IDENT_FID ) fail("Unknown tag id %08X in directory\n", fid->descTag.tagIdent); // check CRC if( fid->fileCharacteristics == FID_FILE_CHAR_PARENT) continue; if( fid->lengthFileIdent == uLen && memcmp( fid->fileIdent, uName, fid->lengthFileIdent) == 0 ) return fid; } return NULL;}/* * Return pointer to new FileEntry in a 2k allocated block to be free'd when no longer required. * Only basic data is filled in. */struct fileEntry* makeFileEntry() { struct fileEntry *fe = (struct fileEntry*) calloc(2048, 1); updateTimestamp(0,0); fe->descTag.tagIdent = TAG_IDENT_FE; fe->descTag.descVersion = 2; fe->descTag.tagSerialNum = lvd->descTag.tagSerialNum; fe->icbTag.strategyType = 4; fe->icbTag.numEntries = 1; fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR; /* User has all permission; Group/Others Read/Exec */ fe->permissions = FE_PERM_U_READ | FE_PERM_U_WRITE | FE_PERM_U_DELETE | FE_PERM_U_CHATTR | FE_PERM_U_EXEC | FE_PERM_G_READ | FE_PERM_G_EXEC | FE_PERM_O_READ | FE_PERM_O_EXEC; fe->fileLinkCount = 1; fe->accessTime = timeStamp; fe->modificationTime = timeStamp; fe->attrTime = timeStamp; fe->impIdent = entityWRUDF; fe->uniqueID = ((struct logicalVolHeaderDesc*)lvid->logicalVolContentsUse)->uniqueID++; return fe;}/* * Return pointer to new FileIdentDesc in an allocated block to be free'd when no longer required. * Does NOT fill: descTag.checksum, descTag.tagLocation, icbTag.characteristics, icb */struct fileIdentDesc*makeFileIdentDesc(char* name) { char uName[256]; int uLen; struct fileIdentDesc *fid; fid = (struct fileIdentDesc*) calloc(512,1); fid->descTag.tagIdent = TAG_IDENT_FID; fid->descTag.descVersion = 2; fid->descTag.tagSerialNum = lvd->descTag.tagSerialNum; fid->fileVersionNum = 1; fid->icb.extLength = 2048; if( name[0] != 0 ) { /* FID to parent directory has no name */ memset(&uName, 0, 256); uLen = encode_utf8(uName, "", name, 256); fid->lengthFileIdent = uLen; memcpy(fid->fileIdent + fid->lengthOfImpUse, uName, fid->lengthFileIdent); } return fid;} int insertFileIdentDesc(Directory *dir, struct fileIdentDesc* fid) { uint32_t lenFid; lenFid = (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3; fid->descTag.descCRCLength = lenFid - sizeof(tag); setChecksum(fid); if( dir->fe.informationLength + lenFid > dir->dataSize ) { if( !(dir->data = realloc(dir->data, dir->dataSize + 2048)) ) { fail("Realloc directory data failed\n"); } dir->dataSize += 2048; } memcpy(dir->data + dir->fe.informationLength, fid, lenFid); dir->fe.informationLength += lenFid; dir->dirDirty = 1; return CMND_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -