hx_morefiles.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:15k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer and/or licensor of the Original Code and owns the copyrights 
  21.  * in the portions it created.  
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /*
  36. This code was descended from Apple Sample Code, but the
  37. code may have been modified.
  38. */
  39. #include "hx_morefiles.h"
  40. #include <string.h>
  41. #ifndef _MAC_MACHO
  42. #include "datetimeutils.h"
  43. #endif
  44. #ifndef _CARBON
  45. #include "MoreFilesExtras.h"
  46. #else
  47. #include "MoreFilesX.h"
  48. #include "hxassert.h"
  49. #endif
  50. #include "hxstrutl.h"
  51. // FSpGetItemSpec
  52. //
  53. // Returns an FSSpec which contains everything but the name of an item contained in the
  54. // specified directory. This merely sets up the returned FSSpec so that the name of the item
  55. // can be copied into the FSSpec, or can easily be used in the FSMakeFSSpec call.
  56. //
  57. //  GR 8/8/01 This was only used by FSpIterateDirectory, and was really inefficient, so it's gone now.
  58. //
  59. // FSpIterateDirectory
  60. //
  61. // Allows for easy iteration of a SINGLE directory. It does not look any deeper than
  62. // the directory with which it starts.  This is to make it quick and easy. 
  63. //
  64. // returns false when the file specified by the "index" is not valid, or any other error
  65. //    happens. Returns true if a file was found at that index.  The index starts at 1.
  66. //
  67. // Note: this is really inefficient if called repeatedly since it has to make an
  68. //       extra call to PBGetCatInfo to figure out the directory's dirID.  It is much
  69. //       better to call FSpGetNthDirectoryItem, below, instead if you will be making
  70. //       repeated calls.
  71. Boolean   FSpIterateDirectory(FSSpec* dirSpec,short index,FSSpec* fileSpec) 
  72. {
  73. OSErr err;
  74. long dirID;
  75. Boolean isDir;
  76. err = FSpGetDirectoryID(dirSpec, &dirID, &isDir);
  77. if ((err == noErr) && isDir)
  78. {
  79. err = FSpGetNthDirectoryItem(dirSpec->vRefNum, dirID, index, fileSpec);
  80. }
  81. return (err == noErr);
  82. }
  83. //
  84. // GetVRefnumFromIndex
  85. //
  86. // Returns the n'th item from the directory specified by vRefNum and dirID.  Can return
  87. // a spec to a directory or to a file.
  88. //
  89. OSErr FSpGetNthDirectoryItem(short vRefNum, long parID, short index, FSSpec *theSpec)
  90. {
  91. OSErr err;
  92. CInfoPBRec cInfo;
  93. theSpec->vRefNum = vRefNum;
  94. theSpec->parID = parID;
  95. cInfo.hFileInfo.ioVRefNum = vRefNum;
  96. cInfo.hFileInfo.ioDirID = parID;
  97. cInfo.hFileInfo.ioNamePtr = theSpec->name;
  98. cInfo.hFileInfo.ioFDirIndex = index; // use vRefNum, dirID and index
  99. err = PBGetCatInfoSync(&cInfo);
  100. return err;
  101. }
  102. //
  103. // GetVRefnumFromIndex
  104. //
  105. // If the return value of this function is true, then the *realrefnum parameter contains
  106. // the RealRefNum of the volume at that index.
  107. //
  108. // the index starts at 1 and continues until you receive an error.
  109. //
  110. Boolean GetVRefnumFromIndex(short index,short *realRefNum) {
  111. Boolean theResult=false;
  112. OSErr err=noErr;
  113. HParamBlockRec pb;
  114. if (realRefNum==0L) goto CleanUp;
  115. memset(&pb,0,sizeof(ParamBlockRec));
  116. pb.volumeParam.ioVolIndex=index;
  117. err=PBHGetVInfoSync(&pb);
  118. *realRefNum=pb.volumeParam.ioVRefNum;
  119. theResult=(err==noErr);
  120. CleanUp:
  121. return(theResult);
  122. }
  123. //
  124. // GetVRefnumFromIndex
  125. //
  126. // If the return value of this function is true, then the *realrefnum parameter contains
  127. // the RealRefNum of the volume at that index.
  128. //
  129. // the index starts at 1 and continues until you receive an error.
  130. //
  131. //
  132. // This version only returns LOCAL UNLOCKED volumes, not remote or locked ones.
  133. //
  134. Boolean GetLocalVRefnumFromIndex(short *index, short *realRefNum)
  135. {
  136. Boolean theResult=false;
  137. OSErr err=noErr;
  138. ParamBlockRec pb;
  139. HParamBlockRec hpb;
  140. Boolean local;
  141. short theSize;
  142. OSType *volTypePtr;
  143. if (realRefNum==0L) goto CleanUp;
  144. do {
  145. (*index)++;
  146. // Get the next volume
  147. memset(&hpb,0,sizeof(HParamBlockRec));
  148. hpb.volumeParam.ioVolIndex = *index;
  149. err=PBHGetVInfoSync(&hpb);
  150. *realRefNum=hpb.volumeParam.ioVRefNum;
  151. theResult=(err==noErr);
  152. local = TRUE;
  153. if (theResult)
  154. {
  155. // Make sure it's unlocked
  156. if ((((unsigned short)hpb.volumeParam.ioVAtrb) & ((unsigned short)32896)) != 0)
  157. local = FALSE;
  158. else
  159. {
  160. // Make sure it's local
  161. memset(&pb,0,sizeof(ParamBlockRec));
  162. pb.ioParam.ioBuffer = (Ptr)&theSize;
  163. pb.ioParam.ioCompletion = NULL;
  164. pb.ioParam.ioVRefNum = *realRefNum;
  165. err = PBGetVolMountInfoSize(&pb);
  166. if (!err)
  167. {
  168. pb.ioParam.ioBuffer = NewPtr((long)theSize);
  169. err = PBGetVolMountInfo(&pb);
  170. if (!err)
  171. {
  172. volTypePtr = (OSType *) &((char *)pb.ioParam.ioBuffer)[2];
  173. if (*volTypePtr=='afpm') // AppleShare volume - we don't want these.
  174. local = FALSE;
  175. }
  176. DisposePtr((Ptr)pb.ioParam.ioBuffer);
  177. }
  178. }
  179. }
  180. } while (theResult && !local);
  181. CleanUp:
  182. return(theResult);
  183. }
  184. //
  185. // FSpGetVersion
  186. //
  187. // Retrieves the version number from a file specified by an FSSpec.
  188. //
  189. Boolean FSpGetVersion(FSSpec *theFile, Byte *majorversion, 
  190.   Byte *minorversion, Byte *revision) {
  191. Handle r=0L;
  192. short saveResFile;
  193. short theResFile=-1;
  194. short vers;
  195. Boolean theResult=false;
  196. saveResFile=CurResFile();
  197. if (theFile == 0L) goto CleanUp;
  198. theResFile=FSpOpenResFile(theFile,fsRdPerm);
  199. if (theResFile != -1) {
  200. r = GetResource('vers',1);
  201. if (r==0L) goto CleanUp;
  202. vers=(short)**r;
  203. if (majorversion != 0L) {
  204. *majorversion = (Byte)vers;
  205. }//if
  206. vers << sizeof(Byte);
  207. if (minorversion != 0L) {
  208. *minorversion = vers | 0xF0;
  209. }//if
  210. if (revision != 0L) {
  211. *revision = vers | 0x0F;
  212. }//if
  213. }//if
  214. CleanUp:
  215. //if (theResFile >=0) CloseResFile(theResFile);
  216. UseResFile(saveResFile);
  217. return(theResult);
  218. }
  219. //
  220. // FSpGetVersionLong
  221. //
  222. // Retrieves the version number from a file specified by an FSSpec. Returns it as a long.
  223. //
  224. Boolean FSpGetVersionLong(FSSpec *theFile, short *theversion) {
  225. Handle r=0L;
  226. short saveResFile;
  227. short theResFile=-1;
  228. Boolean theResult=false;
  229. saveResFile=CurResFile();
  230. if (theFile == 0L) goto CleanUp;
  231. if (theversion == 0L) goto CleanUp;
  232. theResFile=FSpOpenResFile(theFile,fsRdPerm);
  233. if (theResFile != -1) {
  234. r = GetResource('vers',1);
  235. if (r==0L) goto CleanUp;
  236. BlockMove(*r,theversion,sizeof(long));
  237. }//if
  238. CleanUp:
  239. //if (theResFile >=0) CloseResFile(theResFile);
  240. UseResFile(saveResFile);
  241. return(theResult);
  242. }
  243. // 
  244. // FSpGetVersionMessage
  245. //
  246. // Retrieves the version message from a file specified by an FSSpec.
  247. //
  248. Boolean FSpGetVersionMessage(FSSpec *theFile, char *theversion, UINT32 ulBufLen) {
  249. Handle r=0L;
  250. short saveResFile;
  251. short theResFile=-1;
  252. Boolean theResult=false;
  253. Str255 message;
  254. saveResFile=CurResFile();
  255. if (theFile == 0L) goto CleanUp;
  256. if (theversion == 0L) goto CleanUp;
  257. theResFile=FSpOpenResFile(theFile,fsRdPerm);
  258. if (theResFile != -1) {
  259. r = GetResource('vers',1);
  260. if (r==0L) goto CleanUp;
  261. HLock(r);
  262. HNoPurge(r);
  263. *r+=(sizeof(Byte)*4)+sizeof(short);
  264. *r+=**r;
  265. BlockMove(*r,message,sizeof(Str255));
  266. #ifdef _CARBON
  267. p2cstrcpy((char*)message, message);
  268. #else
  269. p2cstr(message);
  270. #endif
  271. SafeStrCpy(theversion,(char *)message, ulBufLen);
  272. }//if
  273. CleanUp:
  274. //if (theResFile >=0) CloseResFile(theResFile);
  275. UseResFile(saveResFile);
  276. return(theResult);
  277. }
  278. // 
  279. // FSpGetFileAge
  280. //
  281. // This function returns the age of a file relative to the current time.
  282. //
  283. // It is legal to pass in NULL if you don't want a particular age granularity.
  284. Boolean
  285. FSpGetFileAge(FSSpec* file,long* minutes,long* seconds,long* ticks)
  286. {
  287. HParmBlkPtr fileinfo=(HParmBlkPtr)NewPtrClear(sizeof(HParamBlockRec));
  288. Boolean theResult=false;
  289. unsigned long curseconds;
  290. GetDateTime(&curseconds); // seconds since 1904
  291. if (file == 0L) goto CleanUp;
  292. if (fileinfo == 0L) goto CleanUp;
  293. fileinfo->fileParam.ioNamePtr=file->name;
  294. fileinfo->fileParam.ioDirID=file->parID;
  295. fileinfo->fileParam.ioVRefNum=file->vRefNum;
  296. if (noErr != PBHGetFInfoSync(fileinfo)) goto CleanUp;
  297. if (ticks != NULL) 
  298. {
  299.     unsigned long createTicks = (fileinfo->fileParam.ioFlCrDat * 60);
  300.     unsigned long curticks = curseconds * 60;
  301.     *ticks=curticks - createTicks;
  302.     if (*ticks < 0)
  303.      *ticks = 0;
  304. }
  305. if (seconds != NULL) 
  306. {
  307.     unsigned long createSecs = fileinfo->fileParam.ioFlCrDat;
  308.     *seconds=curseconds - createSecs;
  309.     if (*seconds < 0)
  310.      *seconds = 0;
  311. }
  312. if (minutes != NULL) 
  313. {
  314.     unsigned long createMinutes = fileinfo->fileParam.ioFlCrDat / 60;
  315.     unsigned long curMinutes = curseconds / 60;
  316.     *minutes = (curMinutes - createMinutes);
  317.     if (*minutes < 0)
  318.      *minutes = 0;
  319. }
  320. theResult=true;
  321. CleanUp:
  322. if (fileinfo != 0L) DisposePtr((Ptr)fileinfo);
  323. return (theResult);
  324. }
  325. Boolean
  326. IsFolder(FSSpec* spec)
  327. {
  328.     long dirID;
  329.     Boolean isDir;
  330.     OSErr err;
  331.     
  332.     err = FSpGetDirectoryID(spec, &dirID, &isDir);
  333.     return ((err == noErr) && isDir);    
  334. }
  335. OSErr GetMoreVInfo(short volref, StringPtr name, unsigned long *volcreated, Boolean *islocked)
  336. {
  337. HVolumeParam block;
  338. OSErr err;
  339. memset(&block, 0x00, sizeof(block));
  340. block.ioVolIndex = 0;
  341. block.ioVRefNum = volref;
  342. block.ioNamePtr = name;
  343. err = PBHGetVInfoSync((HParmBlkPtr)&block);
  344. if (!err) {
  345. if (islocked) *islocked = (block.ioVAtrb & (1<<7)) != 0;
  346. if (volcreated) *volcreated = block.ioVCrDate;
  347. }
  348. return err;
  349. }
  350. #ifdef _CARBON
  351. // Stuff that used to be in MoreFilesExtras but isn't in MoreFilesX in FSSpec form
  352. OSErr FSpGetDirectoryID(const FSSpec* pDirSpec, long *pDirID, Boolean *pIsDir)
  353. {
  354. FSRef dirRef;
  355. Boolean isDir = false;
  356. long dirID = 0;
  357. OSErr err;
  358. err = FSpMakeFSRef(pDirSpec, &dirRef);
  359. if (err == noErr)
  360. {
  361. err = FSGetNodeID(&dirRef, &dirID, &isDir);
  362. }
  363. if (pDirID) *pDirID = dirID;
  364. if (pIsDir) *pIsDir = isDir;
  365. return err;
  366. }
  367. OSErr FSpMoveRenameCompat(const FSSpec * srcSpec, const FSSpec * dstSpec, ConstStr255Param  copyName)
  368. {
  369. FSRef srcRef, destDirRef, newRef;
  370. HFSUniStr255 hfsUniName;
  371. OSErr err;
  372. err = FSpMakeFSRef(srcSpec, &srcRef);
  373. require_noerr(err, CantMakeSrcRef);
  374. err = FSpMakeFSRef(dstSpec, &destDirRef);
  375. require_noerr(err, CantMakeDestRef);
  376. if (copyName)
  377. {
  378. err = HFSNameGetUnicodeName(copyName, kTextEncodingUnknown, &hfsUniName);
  379. require_noerr(err, CantMakeUnicodeName);
  380. }
  381. err = FSMoveRename(&srcRef, &destDirRef, hfsUniName.length, copyName ? hfsUniName.unicode : NULL,
  382. kTextEncodingUnknown, &newRef);
  383. require_noerr(err, CantMoveRename);
  384. return noErr;
  385. // reverse-order cleanup
  386. CantMoveRename:
  387. CantMakeUnicodeName:
  388. CantMakeDestRef:
  389. CantMakeSrcRef:
  390. return err;
  391. }
  392. OSErr DeleteDirectory(short vRefNum, long dirID, ConstStr255Param name)
  393. {
  394. FSRef dirRef;
  395. OSErr err;
  396. err = FSMakeFSRef(vRefNum, dirID, name, &dirRef);
  397. if (err == noErr)
  398. {
  399. err = FSDeleteContainerContents(&dirRef);
  400. }
  401. return err;
  402. }
  403. OSErr FSpFileCopy(const FSSpec *srcSpec, const FSSpec *dstSpec, ConstStr255Param copyName,
  404. void *copyBufferPtr, long copyBufferSize, Boolean preflight)
  405. {
  406. // Ultimately, this should be replaced with a new one that accompanies MoreFilesX, but that's not
  407. // yet available from Apple
  408. void *pBuff = NULL;
  409. long dirID;
  410. Str255 newName;
  411. FSSpec newSpec;
  412. short srcRefNum = -1;
  413. short destRefNum = -1;
  414. FInfo fInfo;
  415. OSErr err;
  416. // get a buffer to use for copying
  417. if (copyBufferPtr)
  418. {
  419. pBuff = copyBufferPtr;
  420. }
  421. else
  422. {
  423. copyBufferSize = 16*1024;
  424. pBuff = NewPtr(copyBufferSize);
  425. }
  426. require_nonnull(pBuff, CantGetBuffer);
  427. // copy the name of the new file
  428. if (copyName)
  429. {
  430. BlockMoveData(&copyName[0], &newName[0], 1 + copyName[0]);
  431. }
  432. else
  433. {
  434. BlockMoveData(&srcSpec->name[0], &newName[0], 1 + srcSpec->name[0]);
  435. }
  436. // make a new file; bail if it already exists
  437. err = FSpGetDirectoryID(dstSpec, &dirID, NULL);
  438. require_noerr(err, CantGetDirID);
  439. err = FSMakeFSSpec(dstSpec->vRefNum, dirID, newName, &newSpec);
  440. require(err == fnfErr, FileExistsAlready);
  441. // create the file
  442. err = FSpCreate(&newSpec, 0, 0, smSystemScript);
  443. require_noerr(err, CantMakeNewFile);
  444. // copy the data forks
  445. err = FSpOpenDF(srcSpec, fsRdPerm, &srcRefNum);
  446. require_noerr(err, CantOpenSourceDF);
  447. err = FSpOpenDF(&newSpec, fsRdWrPerm, &destRefNum);
  448. require_noerr(err, CantOpenDestDF);
  449. err = FSCopyFork(srcRefNum, destRefNum, pBuff, copyBufferSize);
  450. require_noerr(err, CantCopyDataFork);
  451. FSClose(srcRefNum);
  452. FSClose(destRefNum);
  453. srcRefNum = -1;
  454. destRefNum = -1;
  455. // copy the resource forks
  456. err = FSpOpenRF(srcSpec, fsRdPerm, &srcRefNum);
  457. require_noerr(err, CantOpenSourceRF);
  458. err = FSpOpenRF(&newSpec, fsRdWrPerm, &destRefNum);
  459. require_noerr(err, CantOpenDestRF);
  460. err = FSCopyFork(srcRefNum, destRefNum, pBuff, copyBufferSize);
  461. require_noerr(err, CantCopyResourceFork);
  462. FSClose(srcRefNum);
  463. FSClose(destRefNum);
  464. srcRefNum = -1;
  465. destRefNum = -1;
  466. // copy Finder info
  467. err = FSpGetFInfo(srcSpec, &fInfo);
  468. require_noerr(err, CantGetFInfo);
  469. fInfo.fdLocation.h = fInfo.fdLocation.v = 0;
  470. fInfo.fdFldr = 0;
  471. fInfo.fdFlags &= ~kHasBeenInited;
  472. err = FSpSetFInfo(&newSpec, &fInfo);
  473. require_noerr(err, CantSetFInfo);
  474. // we're done with the buffer; dispose it if we allocated it here
  475. if (copyBufferPtr == NULL)
  476. {
  477. DisposePtr((Ptr) pBuff);
  478. }
  479. return noErr;
  480. // reverse-order cleanup
  481. CantSetFInfo:
  482. CantGetFInfo:
  483. CantCopyResourceFork:
  484. CantOpenDestRF:
  485. CantOpenSourceRF:
  486. CantCopyDataFork:
  487. if (destRefNum != -1) FSClose(destRefNum);
  488. CantOpenDestDF:
  489. if (srcRefNum != -1) FSClose(srcRefNum);
  490. CantOpenSourceDF:
  491. FSpDelete(&newSpec);
  492. CantMakeNewFile:
  493. FileExistsAlready:
  494. CantGetDirID:
  495. if (pBuff && !copyBufferPtr)
  496. {
  497. DisposePtr((Ptr) pBuff);
  498. }
  499. CantGetBuffer:
  500. return err;
  501. }
  502. #endif