hx_morefiles.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:16k
源码类别:

Symbian

开发平台:

Visual C++

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