You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测64位Carbon中PBXLockRange()及文件锁在指定卷的可用性?

Carbon文件范围锁功能的检测问题

我了解Carbon已被弃用,但部分功能仍可正常工作,且提供Cocoa或Core Foundation不具备的特性。其中,64位Carbon保留了处理文件范围锁的功能,PBXLockRangeSync()和PBXLockRange()函数的文档说明如下:

锁定forkRefNum指定文件分支的字节范围,仅部分卷格式支持该功能。

经测试发现,这些函数在本地文件系统无法工作,但在共享卷中可正常运行。目前已在两个AFP共享卷测试,多台电脑修改同一文件未出现损坏,本地卷调用时会返回“未实现”类错误。

我想了解是否有熟悉macOS旧版编程的开发者知晓如何检测文件系统是否支持该功能?

目前我遇到困惑:苹果技术笔记(Tech Note)中的卷文件锁支持检测代码,返回结果与PBXLockRange()的实际可用情况完全相反——本地磁盘返回TRUE,而PBXLockRange()可用的共享卷返回FALSE。以下是适配64位Carbon的检测代码(32位旧版Mac OS测试结果一致):

#ifndef gestaltFSSupportsExclusiveLocks
   #define  gestaltFSSupportsExclusiveLocks    15
   #define  bSupportsExclusiveLocks            18
#endif


Boolean  VolumeSupportsExclusiveFileAccess (short vRefNum)
{
   OSErr    err;
   SInt32   response;
   Boolean  exclusiveAccess = FALSE;
   
   err = Gestalt (gestaltFSAttr, &response);
   
   if (!err && (response & (1L << gestaltFSSupportsExclusiveLocks)))  {
  
      GetVolParmsInfoBuffer  vparams = { 0 };  
     
      OSStatus  status = FSGetVolumeParms (vRefNum, // use default volume   
                                           &vparams, // write  
                                           sizeof(GetVolParmsInfoBuffer));  

      if (!status)
         exclusiveAccess = (vparams.vMExtendedAttributes & (1L << bSupportsExclusiveLocks)) != 0;
   }

   return (exclusiveAccess);
}

另外,我曾尝试检测卷是否为共享卷,但FSGetVolumeParms()返回的GetVolParmsInfoBuffer中vMAttrib或vMExtendedAttributes无“共享卷”标识。

编辑:发现可通过NSURL的-getResourceValue:forKey:error:方法结合NSURLVolumeIsLocalKey解决该问题。

编辑2:后续发现NSURLVolumeSupportsAdvisoryFileLockingKey结合该方法的检测结果与其他方法一致——值为真时无法使用锁,值为假时可使用锁。

最终,我编写了可在32位和64位Carbon中检测共享卷的代码:

Boolean  VolumeIsSharedVolume (short vRefNum, Boolean *supportsFileLocks)  // ExclusiveFileAccess
{
   OSErr    err;
   SInt32   response;
   Boolean  exclusiveLocks = FALSE;
   Boolean  volumeIsShared = FALSE;
   
   GetVolParmsInfoBuffer  volParmsBuffer = { 0 };
   
   err = Gestalt (gestaltSystemVersion, &response);
   
   if ((err == noErr) && (response < 0x01000))  {
      err = Gestalt (gestaltMacOSCompatibilityBoxAttr, &response);
      if ((err != noErr) || ((response & (1 << gestaltMacOSCompatibilityBoxPresent)) == 0))
         return (TRUE);        //    Running on Mac OS 9, not in Classic
   }

   err = Gestalt (gestaltFSAttr, &response);
   
   if (!err && (response & (1L << gestaltFSSupportsExclusiveLocks)))  {
      
#if __LP64__

      err = FSGetVolumeParms (vRefNum, &volParmsBuffer, sizeof(GetVolParmsInfoBuffer));
      
#else

      HParamBlockRec  hPB;

      hPB.ioParam.ioVRefNum     = vRefNum;
      hPB.ioParam.ioNamePtr     = NULL;
      hPB.ioParam.ioBuffer      = (Ptr) &volParmsBuffer;
      hPB.ioParam.ioReqCount    = sizeof (volParmsBuffer);
      
      err = PBHGetVolParmsSync (&hPB);

#endif  // __LP64__

      if (!err)  {
         exclusiveLocks = (volParmsBuffer.vMExtendedAttributes & (1L << bSupportsExclusiveLocks)) != 0;
         if (volParmsBuffer.vMServerAdr)
            volumeIsShared = TRUE;
      }
   }
   
   if (supportsFileLocks)
      *supportsFileLocks = exclusiveLocks;

   return (volumeIsShared);
}

该代码在AFP和SMB共享卷中表现一致,多客户端混合修改文件时锁功能正常,已在Mac OS服务器和群晖NAS测试,后续计划加入Windows客户端测试。


内容的提问来源于stack exchange,提问作者IgorD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 19:30:01