Ticket #9081: AmigaOS4.diff
File AmigaOS4.diff, 12.6 KB (added by , 15 years ago) |
---|
-
backends/fs/amigaos4/amigaos4-fs.cpp
43 43 #define ENTER() /* debug(6, "Enter") */ 44 44 #define LEAVE() /* debug(6, "Leave") */ 45 45 46 const uint32 kExAllBufferSize = 40960; // TODO: is this okay for sure?47 48 46 /** 49 47 * Implementation of the ScummVM file system API. 50 48 * … … 57 55 Common::String _sPath; 58 56 bool _bIsDirectory; 59 57 bool _bIsValid; 58 uint32 _nProt; 60 59 61 60 /** 62 * Obtain the FileInfoBlock protection value for this FSNode, 63 * as defined in the <proto/dos.h> header. 64 * 65 * @return -1 if there were errors, 0 or a positive integer otherwise. 61 * Creates a list with all the volumes present in the root node. 66 62 */ 67 virtual int getFibProtection() const;63 virtual AbstractFSList listVolumes() const; 68 64 69 65 public: 70 66 /** 71 * Creates a AmigaOSFilesystemNode with the root node as path.67 * Creates an AmigaOSFilesystemNode with the root node as path. 72 68 */ 73 69 AmigaOSFilesystemNode(); 74 70 75 71 /** 76 * Creates a AmigaOSFilesystemNode for a given path.72 * Creates an AmigaOSFilesystemNode for a given path. 77 73 * 78 74 * @param path Common::String with the path the new node should point to. 79 75 */ 80 76 AmigaOSFilesystemNode(const Common::String &p); 81 77 82 78 /** 83 * FIXME: document this constructor. 79 * Creates an AmigaOSFilesystemNode given its lock and display name 80 * 81 * @param pLock BPTR to the lock. 82 * @param pDisplayName name to be used for display, in case not supplied the FilePart() of the filename will be used. 83 * 84 * @note This shouldn't even be public as it's only internally, at best it should have been protected if not private 84 85 */ 85 86 AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayName = 0); 86 87 87 88 89 90 91 88 /** 89 * Copy constructor. 90 * 91 * @note Needed because it duplicates the file lock 92 */ 92 93 AmigaOSFilesystemNode(const AmigaOSFilesystemNode &node); 93 94 94 95 /** … … 110 111 111 112 virtual Common::SeekableReadStream *createReadStream(); 112 113 virtual Common::WriteStream *createWriteStream(); 113 114 /**115 * Creates a list with all the volumes present in the root node.116 */117 virtual AbstractFSList listVolumes() const;118 114 }; 119 115 120 116 /** … … 149 145 _bIsDirectory = true; 150 146 _sPath = ""; 151 147 _pFileLock = 0; 148 _nProt = 0; // protection is ignored for the root volume 152 149 LEAVE(); 153 150 } 154 151 … … 169 166 _pFileLock = 0; 170 167 _bIsDirectory = false; 171 168 172 struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL);173 if (!fib) {174 debug(6, "FileInfoBlock is NULL");175 LEAVE();176 return;177 }178 179 169 // Check whether the node exists and if it is a directory 180 BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK);181 if (p Lock) {182 if (IDOS->Examine(pLock, fib) != DOSFALSE) {183 if (FIB_IS_DRAWER(fib)) {184 185 _pFileLock = IDOS->DupLock(pLock);186 170 struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_StringNameInput,_sPath.c_str(),TAG_END); 171 if (pExd) { 172 _nProt = pExd->Protection; 173 if (EXD_IS_DIRECTORY(pExd)) { 174 _bIsDirectory = true; 175 _pFileLock = IDOS->Lock((CONST_STRPTR)_sPath.c_str(), SHARED_LOCK);; 176 _bIsValid = (_pFileLock != 0); 187 177 188 // Add a trailing slash if it is needed 189 const char c = _sPath.lastChar(); 190 if (c != '/' && c != ':') 191 _sPath += '/'; 192 } 193 else { 194 //_bIsDirectory = false; 195 _bIsValid = true; 196 } 178 // Add a trailing slash if it is needed 179 const char c = _sPath.lastChar(); 180 if (c != '/' && c != ':') 181 _sPath += '/'; 197 182 } 183 else { 184 //_bIsDirectory = false; 185 _bIsValid = true; 186 } 198 187 199 IDOS-> UnLock(pLock);188 IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd); 200 189 } 201 190 202 IDOS->FreeDosObject(DOS_FIB, fib);203 191 LEAVE(); 204 192 } 205 193 … … 232 220 _bIsValid = false; 233 221 _bIsDirectory = false; 234 222 235 struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL); 236 if (!fib) { 237 debug(6, "FileInfoBlock is NULL"); 238 LEAVE(); 239 return; 240 } 241 242 if (IDOS->Examine(pLock, fib) != DOSFALSE) { 243 if (FIB_IS_DRAWER(fib)) { 223 struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_FileLockInput,pLock,TAG_END); 224 if (pExd) { 225 _nProt = pExd->Protection; 226 if (EXD_IS_DIRECTORY(pExd)) { 244 227 _bIsDirectory = true; 245 228 _pFileLock = IDOS->DupLock(pLock); 246 229 _bIsValid = _pFileLock != 0; … … 253 236 //_bIsDirectory = false; 254 237 _bIsValid = true; 255 238 } 239 240 IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd); 256 241 } 242 else { 243 debug(6, "ExamineObject() returned NULL"); 244 } 257 245 258 IDOS->FreeDosObject(DOS_FIB, fib);259 246 LEAVE(); 260 247 } 261 248 262 249 // We need the custom copy constructor because of DupLock() 263 AmigaOSFilesystemNode::AmigaOSFilesystemNode(const AmigaOSFilesystemNode& node) { 250 AmigaOSFilesystemNode::AmigaOSFilesystemNode(const AmigaOSFilesystemNode& node) 251 : AbstractFSNode() { 264 252 ENTER(); 265 253 _sDisplayName = node._sDisplayName; 266 254 _bIsValid = node._bIsValid; 267 255 _bIsDirectory = node._bIsDirectory; 268 256 _sPath = node._sPath; 269 257 _pFileLock = IDOS->DupLock(node._pFileLock); 258 _nProt = node._nProt; 270 259 LEAVE(); 271 260 } 272 261 … … 284 273 285 274 bool nodeExists = false; 286 275 287 struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL); 288 if (!fib) { 289 debug(6, "FileInfoBlock is NULL"); 290 LEAVE(); 291 return false; 292 } 293 294 BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK); 276 // previously we were trying to examine the node in order 277 // to determine if the node exists or not. 278 // I don't see the point : once you have been granted a 279 // lock on it then it means it exists... 280 // 281 // ============================= Old code 282 // BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK); 283 // if (pLock) 284 // { 285 // if (IDOS->Examine(pLock, fib) != DOSFALSE) 286 // nodeExists = true; 287 // IDOS->UnLock(pLock); 288 // } 289 // 290 // IDOS->FreeDosObject(DOS_FIB, fib); 291 // 292 // ============================= New code 293 BPTR pLock = IDOS->Lock(_sPath.c_str(), SHARED_LOCK); 295 294 if (pLock) { 296 if (IDOS->Examine(pLock, fib) != DOSFALSE) 297 nodeExists = true; 295 nodeExists = true; 298 296 IDOS->UnLock(pLock); 299 297 } 300 298 301 IDOS->FreeDosObject(DOS_FIB, fib);302 299 LEAVE(); 303 300 return nodeExists; 304 301 } … … 323 320 324 321 bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const { 325 322 ENTER(); 323 bool ret = false; 326 324 327 325 //TODO: honor the hidden flag 326 // There is nothing like a hidden flag under AmigaOS... 328 327 329 328 if (!_bIsValid) { 330 329 debug(6, "Invalid node"); … … 345 344 return true; 346 345 } 347 346 348 struct ExAllControl *eac = (struct ExAllControl *)IDOS->AllocDosObject(DOS_EXALLCONTROL, 0); 349 if (eac) { 350 struct ExAllData *data = (struct ExAllData *)IExec->AllocVec(kExAllBufferSize, MEMF_ANY); 351 if (data) { 352 BOOL bExMore; 353 eac->eac_LastKey = 0; 354 do { 355 // Examine directory 356 bExMore = IDOS->ExAll(_pFileLock, data, kExAllBufferSize, ED_TYPE, eac); 347 APTR context = IDOS->ObtainDirContextTags( EX_FileLockInput, _pFileLock, 348 EX_DoCurrentDir, TRUE, /* for softlinks */ 349 EX_DataFields, (EXF_NAME|EXF_LINK|EXF_TYPE), 350 TAG_END); 351 if (context) { 352 struct ExamineData * pExd = NULL; // NB: no need to free value after usage, all is dealt by the DirContext release 357 353 358 LONG error = IDOS->IoErr(); 359 if (!bExMore && error != ERROR_NO_MORE_ENTRIES) 360 break; // Abnormal failure 361 362 if (eac->eac_Entries == 0) 363 continue; // Normal failure, no entries 364 365 struct ExAllData *ead = data; 366 do { 367 if ((mode == Common::FSNode::kListAll) || 368 (EAD_IS_DRAWER(ead) && (mode == Common::FSNode::kListDirectoriesOnly)) || 369 (EAD_IS_FILE(ead) && (mode == Common::FSNode::kListFilesOnly))) { 370 Common::String full_path = _sPath; 371 full_path += (char*)ead->ed_Name; 372 373 BPTR lock = IDOS->Lock((STRPTR)full_path.c_str(), SHARED_LOCK); 374 if (lock) { 375 AmigaOSFilesystemNode *entry = new AmigaOSFilesystemNode(lock, (char *)ead->ed_Name); 376 if (entry) { 377 //FIXME: since the isValid() function is no longer part of the AbstractFSNode 378 // specification, the following call had to be changed: 379 // if (entry->isValid()) 380 // Please verify that the logic of the code remains coherent. Also, remember 381 // that the isReadable() and isWritable() methods are available. 382 if (entry->exists()) 383 myList.push_back(entry); 384 else 385 delete entry; 386 } 387 IDOS->UnLock(lock); 388 } 354 AmigaOSFilesystemNode *entry ; 355 while( (pExd = IDOS->ExamineDir(context)) ) { 356 if( (EXD_IS_FILE(pExd) && ( Common::FSNode::kListFilesOnly == mode )) 357 || (EXD_IS_DIRECTORY(pExd) && ( Common::FSNode::kListDirectoriesOnly == mode )) 358 || Common::FSNode::kListAll == mode 359 ) 360 { 361 BPTR pLock = IDOS->Lock( pExd->Name, SHARED_LOCK ); 362 if( pLock ) { 363 entry = new AmigaOSFilesystemNode( pLock, pExd->Name ); 364 if( entry ) { 365 myList.push_back(entry); 389 366 } 390 ead = ead->ed_Next;391 } while (ead);392 } while (bExMore);393 367 394 IExec->FreeVec(data); 368 IDOS->UnLock(pLock); 369 } 370 } 395 371 } 372 if( ERROR_NO_MORE_ENTRIES != IDOS->IoErr() ) { 373 debug(6, "An error occured during ExamineDir"); 374 ret = false; 375 } 376 else { 377 ret = true; 378 } 396 379 397 IDOS->FreeDosObject(DOS_EXALLCONTROL, eac);398 }399 380 400 LEAVE(); 401 402 return true; 403 } 404 405 int AmigaOSFilesystemNode::getFibProtection() const { 406 ENTER(); 407 408 int fibProt = -1; 409 struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL); 410 if (!fib) { 411 debug(6, "FileInfoBlock is NULL"); 412 LEAVE(); 413 return fibProt; 381 IDOS->ReleaseDirContext(context); 414 382 } 415 416 BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK); 417 if (pLock) { 418 if (IDOS->Examine(pLock, fib) != DOSFALSE) { 419 fibProt = fib->fib_Protection; 420 } 421 IDOS->UnLock(pLock); 383 else { 384 debug(6, "Unable to ObtainDirContext"); 385 ret = false; 422 386 } 423 387 424 IDOS->FreeDosObject(DOS_FIB, fib);425 388 LEAVE(); 426 return fibProt; 389 390 return ret; 427 391 } 428 392 429 393 AbstractFSNode *AmigaOSFilesystemNode::getParent() const { … … 457 421 } 458 422 459 423 bool AmigaOSFilesystemNode::isReadable() const { 460 bool readable = false; 461 int fibProt = getFibProtection(); 424 // Regular RWED protection flags are low-active or inverted, thus the negation. 425 // moreover pseudo root filesystem (null _pFileLock) is readable whatever the 426 // protection says 427 bool readable = !(_nProt & EXDF_READ) || _pFileLock == 0; 462 428 463 if (fibProt >= 0) {464 /* The fib_Protection flag is low-active or inverted, thus the negation.465 *466 * For more information, consult the compiler/include/dos/dos.h467 * file from the AROS source (http://aros.sourceforge.net/).468 */469 readable = !(fibProt & FIBF_READ);470 }471 472 429 return readable; 473 430 } 474 431 475 432 bool AmigaOSFilesystemNode::isWritable() const { 476 bool writable = false; 477 int fibProt = getFibProtection(); 433 // Regular RWED protection flags are low-active or inverted, thus the negation. 434 // moreover pseudo root filesystem (null _pFileLock) is never writable whatever 435 // the protection says (because of the pseudo nature) 436 bool writable = !(_nProt & EXDF_WRITE) && _pFileLock !=0; 478 437 479 if (fibProt >= 0) {480 /* The fib_Protection flag is low-active or inverted, thus the negation.481 *482 * For more information, consult the compiler/include/dos/dos.h483 * file from the AROS source (http://aros.sourceforge.net/).484 */485 writable = !(fibProt & FIBF_WRITE);486 }487 488 438 return writable; 489 439 } 490 440 491 AbstractFSList AmigaOSFilesystemNode::listVolumes() 441 AbstractFSList AmigaOSFilesystemNode::listVolumes() const { 492 442 ENTER(); 493 443 494 444 AbstractFSList myList; … … 508 458 if (dosList->dol_Type == DLT_VOLUME && 509 459 dosList->dol_Name && 510 460 dosList->dol_Task) { 511 //const char *volName = (const char *)BADDR(dosList->dol_Name)+1;512 461 513 462 // Copy name to buffer 514 463 IDOS->CopyStringBSTRToC(dosList->dol_Name, buffer, MAXPATHLEN); 515 464 516 //const char *devName = (const char *)((struct Task *)dosList->dol_Task->mp_SigTask)->tc_Node.ln_Name;517 518 465 // Volume name + '\0' 519 466 char *volName = new char [strlen(buffer) + 1]; 520 467 … … 536 483 537 484 AmigaOSFilesystemNode *entry = new AmigaOSFilesystemNode(volumeLock, buffer); 538 485 if (entry) { 539 //FIXME: since the isValid() function is no longer part of the AbstractFSNode 540 // specification, the following call had to be changed: 541 // if (entry->isValid()) 542 // Please verify that the logic of the code remains coherent. Also, remember 543 // that the isReadable() and isWritable() methods are available. 544 if(entry->exists()) 545 myList.push_back(entry); 546 else 547 delete entry; 486 myList.push_back(entry); 548 487 } 549 488 550 489 IDOS->UnLock(volumeLock);