]> git.saurik.com Git - apple/xnu.git/blob - bsd/hfs/hfscommon/Misc/VolumeRequests.c
xnu-123.5.tar.gz
[apple/xnu.git] / bsd / hfs / hfscommon / Misc / VolumeRequests.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 File: VolumeRequests.c
24
25 Contains: MountVolume and related utility routines for HFS & HFS Plus
26
27 Version: HFS Plus 1.0
28
29 Written by: Deric Horn
30
31 Copyright: © 1996-1998 by Apple Computer, Inc., all rights reserved.
32
33 File Ownership:
34
35 DRI: Deric Horn
36
37 Other Contacts: Mark Day, Don Brady
38
39 Technology: File Systems
40
41 Writers:
42
43 (JL) Jim Luther
44 (msd) Mark Day
45 (DSH) Deric Horn
46 (djb) Don Brady
47
48 Change History (most recent first):
49 <MacOSX> 7/28/98 djb GetDiskBlocks is now implemented in MacOSStubs.c (radar #2258148).
50 <MacOSX> 4/3/98 djb Conditionally remove FSVars reference from GetVolumeNameFromCatalog.
51 <MacOSX> 3/31/98 djb Sync up with final HFSVolumes.h header file.
52 <CS47> 1/29/98 DSH TrashAllFSCaches is responsible for trashing all file system and
53 disk caches. Called from FlushVol when the HFS bit is set.
54 <CS46> 12/12/97 DSH 2003877, when vcbAllocPtr was copied to nextAllocation it was
55 getting sign extended.
56 <CS45> 11/26/97 DSH 2003459, fcbs was not being initialized if volume was offline
57 and we are executing an unconditional unmount.
58 <CS44> 11/24/97 DSH 2005507, FlushVolumeControlBlock() keeps MDB drCrDate in sync
59 with VolumeHeader createDate.
60 <CS43> 11/11/97 DSH 1685873, RemountWrappedVolumes was only remounting the first
61 HFS+ volume in the queue, causing HFS wrappers to be mounted if
62 multiple volumes had been mounted before InitHFSPlus.
63 <CS42> 11/4/97 DSH Clear FCB when getting a new one.
64 <CS41> 11/3/97 JL #2001483 - Removed unneeded parameters from MountVolume,
65 MountHFSVolume, MountHFSPlusVolume, GetVolumeInformation,
66 GetXVolumeInformation and AddVCB (and added local variables as
67 needed). Return WDCBRecPtr from UnMountVolume. Set wdcb
68 parameter to NULL in GetXVolumeInformation if working directory
69 was not specified.
70 <CS40> 10/31/97 DSH Added consistencyStatus parameter to MountCheck
71 <CS39> 10/23/97 msd Bug 1685113. The VolumeHeader's createDate should be in local
72 time (not GMT) and identical to the MDB's drCrDate (and VCB's
73 vcbCrDate). When checking for a remount of an offline HFS Plus
74 volume, compare write counts instead of mod dates (which could
75 be fooled by the user changing time zones). Force MountCheck to
76 run if the volume was last mounted by Bride 1.0b2 or earlier.
77 <CS38> 10/17/97 msd Conditionalize DebugStrs.
78 <CS37> 10/13/97 djb Update volumeNameEncodingHint when updating the volume name.
79 <CS36> 10/10/97 msd Bug 1683571. The dates in the volume header are in GMT, so be
80 sure to convert them when mounting a volume or flushing the
81 volume header.
82 <CS35> 10/2/97 DSH In UnmountVolume() check that the drive is on line before
83 determining if wrapper volume needs to be renamed causing IO.
84 <CS34> 10/1/97 DSH Run on disk version of MountCheck instead of ROM version for
85 boot volumes1682475.
86 <CS33> 10/1/97 djb Add calls to InvalidateCatalogCache (part of radar #1678833).
87 <CS32> 9/26/97 DSH Removed debugging code: support for 'W' key wrapper mounting.
88 <CS31> 9/17/97 DSH hfsPlusIOPosOffset was uninitialized for Wrapperless volumes.
89 <CS30> 9/5/97 djb In MountVol initialize Catalog cache before calling Catalog!
90 <CS29> 9/4/97 msd PropertyCloseVolume renamed to AttributesCloseVolume. Remove
91 call to AttributesOpenVolume (it no longer exists).
92 <CS28> 9/2/97 DSH VolumeHeader is now 3rd sector in partition, altVH is 2nd to
93 last cor compatability. Initial support for wrapperless
94 volumes.
95 <CS27> 8/26/97 djb Only call CountRootFiles during MountVol.
96 <CS26> 8/20/97 msd If the HFS Plus volume version doesn't match, mount the wrapper
97 instead.
98 <CS25> 8/19/97 djb Add error handling to RenameWrapperVolume.
99 <CS24> 8/15/97 msd Bug 1673999. In MakeVCBsExtendedVCBs, copy old VCB's vcbAllocPtr
100 to new VCB's nextAllocation field.
101 <CS23> 8/12/97 djb Fixed GetXVolInfo to only use extended vcb fields for local
102 volumes (radar# 1673177)
103 <CS22> 8/11/97 DSH vcbNmAlBlks is now taken from the embededExtent.blockCount
104 (1669121).
105 <CS21> 8/11/97 djb Return actual count of files in root directory for HFS Plus
106 volumes (Radar #1669118). Added local CountRootFiles routine.
107 8/5/97 msd Make sure version field in VolumeHeader is exactly
108 kHFSPlusVersion. 8/1/97 djb GetXVolumeInformation now returns
109 extFSErr when FSID is nonzero (Radar #1649503).
110 <CS20> 7/25/97 DSH Init and Dispose of GenericMRUCache within ExtendedVCB.
111 <CS19> 7/16/97 DSH FilesInternal.x -> FileMgrInternal.x to avoid name collision
112 <CS18> 7/15/97 DSH Remount Wrapper volumes mounted before HFS+ initialization
113 (166729)
114 <CS17> 7/15/97 djb Remove ioXVersion checking in GetXVolInfo (radar #1666217).
115 <CS16> 7/8/97 DSH Loading PrecompiledHeaders from define passed in on C line
116 <CS15> 7/7/97 djb Add GetVolumeNameFromCatalog routine.
117 <CS14> 7/7/97 DSH GetNewVRefNum now get's a recycled vRefNum. Bug 1664445 in
118 Installer was cacheing the vRefNum while CheckDisk unmounts and
119 remounts disk.
120 <CS13> 6/30/97 DSH shadowing values obsoleteVCBXTRef, and obsoleteVCBCTRef when
121 HFS+ volume is mounted.
122 <CS12> 6/26/97 DSH GetVolInfo returns HFS signature for HFS+ volumes, GetXVolInfo
123 returns real signature.
124 <CS11> 6/24/97 DSH MakeVCBsExtendedVCBs was using wdcb->count as count not byte
125 count.
126 <CS10> 6/18/97 djb Set/get volume encodingsBitmap.
127 <CS9> 6/16/97 msd Include String.h and Disks.h.
128 <CS8> 6/12/97 djb Get in sync with HFS Plus format changes.
129 <CS7> 6/11/97 msd Make GetXVolumeInformation return true allocation block size. It
130 now checks the ioXVersion field.
131 <CS6> 5/28/97 msd When flushing the volume header, write out the allocation file's
132 clump size (from the FCB). When mounting an HFS Plus volume,
133 zero the entire FCB extent record, not just the first extent,
134 for the various volume control files.
135 <CS5> 5/19/97 djb Add calls to CreateVolumeCatalogCache,
136 DisposeVolumeCatalogCache.
137 <CS4> 5/9/97 djb Get in sync with new FilesInternal.i
138 <CS3> 5/8/97 DSH Only mount HFS+ volumes with version < 2.0 in the VolumeHeader.
139 Return wrgVolTypErr if too new.
140 <CS2> 5/2/97 djb Disable Manual Eject code since its buggy!
141 <CS1> 4/25/97 djb first checked in
142
143 <HFS32> 4/11/97 DSH MountHFSPlusVolume gets volume name from catalog, and
144 UnmountVolume shadows the name back to the wrapper partition.
145 <HFS31> 4/8/97 msd Once volume is mounted, call AttributesOpenVolume to allow a
146 buffer to be allocated.
147 <HFS30> 4/7/97 msd In FlushVolumeControlBlock, don't update the attributes BTree
148 fields in the Volume Header unless an attributes BTree was
149 already open.
150 <HFS29> 4/7/97 msd In SetupFCB, add case for attributes BTree. Add code to set up
151 the attributes BTree. Remove call to PropertyOpenVolume. In
152 FlushVolumeControlBlock, write out any changes to the attributes
153 BTree.
154 <HFS28> 4/4/97 djb Get in sync with volume format changes.
155 <HFS27> 3/31/97 djb Added catalogDataCache to VCB; Remove ClearMem routine.
156 <HFS26> 3/18/97 msd In MountHFSPlusVolume, the free blocks calculation can overflow,
157 setting vcbFreeBks to a too-small value.
158 <HFS25> 3/17/97 DSH Added some utility functions AddVCB, GetParallelFCBFromRefNum,
159 casting for SC, and made some functions extern for DFA.
160 <HFS24> 3/5/97 msd Add calls to Property Manager to open and close the volume. When
161 unmounting an HFS+ volume, the allocation (bitmap) file now gets
162 closed.
163 <HFS23> 2/19/97 djb Update to 16-bit HFS Plus signature.
164 <HFS22> 2/12/97 msd In GetXVolumeInformation, the result code could be
165 uninitialized.
166 <HFS21> 1/23/97 DSH UpdateAlternateVoumeControlBlock()
167 <HFS20> 1/15/97 djb Remove MountCheckStub. Add file names to fcbs for debugging.
168 <HFS19> 1/13/97 DSH Use ExtendedVCB nextAllocation instead of vcbAllocPtr through
169 all code.
170 <HFS18> 1/9/97 djb Get in sync with new VolumeHeader and Extended VCB.
171 <HFS17> 1/6/97 djb Changed API to ParallelFCBFromRefnum (pragma parameter was
172 broken).
173 <HFS16> 1/6/97 msd Set only the defined bits in the MDB drAtrb field (when copying
174 from VCB vcbAtrb field).
175 <HFS15> 1/6/97 DSH CloseFile requires VCB to be passed in.
176 <HFS14> 1/6/97 djb FlushVolumeControlBlock was writing to absolute block 0 instead
177 of to block zero of the embedded volume.
178 <HFS13> 12/20/96 msd A comparison was using "=" instead of "=="; might have caused
179 the wrong volume to be set as the default.
180 <HFS12> 12/19/96 DSH Setting up ExtendedVCBs
181 <HFS11> 12/19/96 djb Updated for new B-tree Manager interface.
182 <HFS10> 12/18/96 msd Change GetVCBRefNum so it can actually return a VCB pointer.
183 <HFS9> 12/12/96 djb Use new SPI for GetCatalogNode.
184 <HFS8> 12/12/96 msd Fix a bunch of errors (mostly type mismatch) when compiling with
185 Metrowerks.
186 <HFS7> 12/12/96 DSH adding some util functions
187 <HFS6> 12/10/96 msd Check PRAGMA_LOAD_SUPPORTED before loading precompiled headers.
188 <HFS5> 12/4/96 DSH Ported GetVolumeInformation & GetXVolumeInformation.
189 <3*> 11/20/96 DSH HFS Plus support to MountVolume
190 <HFS3> 11/20/96 DSH Added UnmountVol and related routines, also backed out <2>
191 because C_FXMKeyCmp is passed as a parameter from C but called
192 from Asm in BTOpen so we need a Case ON Asm entry point.
193 <HFS2> 11/20/96 msd Use CompareExtentKeys() instead of CFXMKeyCmp().
194 <HFS1> 11/19/96 DSH first checked in
195 <1> 11/19/96 DSH first checked in
196
197 */
198 #include <sys/param.h>
199 #include <sys/systm.h>
200 #include <sys/kernel.h>
201 #include <sys/vnode.h>
202 #include <sys/malloc.h>
203
204 #include "../../hfs.h"
205 #include "../../hfs_endian.h"
206
207 #include "../headers/FileMgrInternal.h"
208
209 #define kIDSectorOffset 2
210
211 OSErr GetNewFCB( ExtendedVCB *vcb, FileReference* fRefPtr);
212
213 OSErr AccessBTree( ExtendedVCB *vcb, FileReference refNum, UInt32 fileID, UInt32 fileClumpSize, void *CompareRoutine );
214
215 UInt16 DivUp( UInt32 byteRun, UInt32 blockSize );
216
217 Boolean IsARamDiskDriver( void );
218
219 OSErr GetVCBRefNum( ExtendedVCB **vcb, short vRefNum );
220
221 OSErr ValidMasterDirectoryBlock( HFSMasterDirectoryBlock *mdb );
222
223 void RenameWrapperVolume( Str27 newVolumeName, UInt16 driveNumber );
224
225 OSErr CheckExternalFileSystem( ExtendedVCB *vcb );
226
227 OSErr FlushVolume( ExtendedVCB *vcb );
228
229 FCB *SetupFCB( ExtendedVCB *vcb, FileReference refNum, UInt32 fileID, UInt32 fileClumpSize );
230
231 void AddVCB( ExtendedVCB *vcb, short driveNumber, short ioDRefNum );
232
233 short IsPressed( unsigned short k );
234
235 FileReference GetNewVRefNum();
236
237 OSErr GetVolumeNameFromCatalog(ExtendedVCB *vcb);
238
239 #if TARGET_API_MAC_OS8
240 static UInt16 CountRootFiles(ExtendedVCB *vcb);
241 #endif /* TARGET_API_MAC_OS8 */
242
243
244 #if ( hasHFSManualEject )
245 static void SetVCBManEject(ExtendedVCB *vcb);
246 #endif
247
248 // External routines
249
250 extern OSErr C_FlushMDB( ExtendedVCB *volume );
251
252 extern OSErr DisposeVolumeCacheBlocks( ExtendedVCB *vcb );
253
254 extern void DisposeVolumeControlBlock( ExtendedVCB *vcb );
255
256 extern OSErr FlushVolumeBuffers( ExtendedVCB *vcb );
257
258 extern void MultiplyUInt32IntoUInt64( UInt64 *wideResult, UInt32 num1, UInt32 num2 );
259
260 extern void TrashCatalogNodeCache( void );
261
262
263 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
264 // Routine: VolumeWritable Asm: CVFlgs
265 //
266 // Function: Check the volume's flags to see if modify requests are allowed.
267 //
268 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
269 OSErr VolumeWritable( ExtendedVCB *vcb )
270 {
271 if ( !(vcb->vcbAtrb & 0x8000) ) // if the volume is not locked
272 {
273 if ( ! (*((Ptr)&(vcb->vcbAtrb) + 1) & kHFSVolumeHardwareLockMask) ) // if it's not write protected
274 return( noErr );
275 else
276 return( wPrErr );
277 }
278 else
279 {
280 return( vLckdErr );
281 }
282 }
283
284
285 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
286 // Routine: DivUp from Asm: DivUp
287 //
288 // Function: Given a number of bytes and block size, calculate the number of
289 // blocks needd to hold all the bytes.
290 //
291 // Result: Number of physical blocks needed
292 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
293 UInt16 DivUp( UInt32 byteRun, UInt32 blockSize )
294 {
295 UInt32 blocks;
296
297 blocks = (byteRun + blockSize - 1) / blockSize; // Divide up, remember this is integer math.
298
299 if ( blocks > 0xffff ) // maximum 16 bit value
300 blocks = 0xffff;
301
302 return( (UInt16) blocks );
303 }
304
305
306
307
308 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
309 // Routine: HFSBlocksFromTotalSectors
310 //
311 // Function: Given the total number of sectors on the volume, calculate
312 // the 16Bit number of allocation blocks, and allocation block size.
313 //
314 // Result: none
315 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
316 void HFSBlocksFromTotalSectors( UInt32 totalSectors, UInt32 *blockSize, UInt16 *blockCount )
317 {
318 UInt16 newBlockSizeInSectors = 1;
319 UInt32 newBlockCount = totalSectors;
320
321 while ( newBlockCount > 0XFFFF )
322 {
323 newBlockSizeInSectors++;
324 newBlockCount = totalSectors / newBlockSizeInSectors;
325 }
326
327 *blockSize = newBlockSizeInSectors * 512;
328 *blockCount = newBlockCount;
329 }
330
331
332
333
334 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
335 // Routine: ValidMasterDirectoryBlock
336 //
337 // Function: Run some sanity checks to make sure the MDB is valid
338 //
339 // Result: error
340 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
341 OSErr ValidMasterDirectoryBlock( HFSMasterDirectoryBlock *mdb )
342 {
343 OSErr err;
344
345 if ( (SWAP_BE16 (mdb->drSigWord) == kHFSPlusSigWord) || (SWAP_BE16 (mdb->drSigWord) == kHFSSigWord) ) // if HFS or HFS Plus volume
346 {
347 if ( (SWAP_BE32 (mdb->drAlBlkSiz) != 0) && ((SWAP_BE32 (mdb->drAlBlkSiz) & 0x01FF) == 0) ) // non zero multiple of 512
348 err = noErr;
349 else
350 err = badMDBErr;
351 }
352 else
353 {
354 err = noMacDskErr;
355 }
356
357 return( err );
358 }
359
360
361 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
362 // Routine: ValidVolumeHeader
363 //
364 // Function: Run some sanity checks to make sure the VolumeHeader is valid
365 //
366 // Result: error
367 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
368 OSErr ValidVolumeHeader( HFSPlusVolumeHeader *volumeHeader )
369 {
370 OSErr err;
371
372 if ( SWAP_BE16 (volumeHeader->signature) == kHFSPlusSigWord && SWAP_BE16 (volumeHeader->version) == kHFSPlusVersion )
373 {
374 if ( (SWAP_BE32 (volumeHeader->blockSize) != 0) && ((SWAP_BE32 (volumeHeader->blockSize) & 0x01FF) == 0) ) // non zero multiple of 512
375 err = noErr;
376 else
377 err = badMDBErr; //\80\80 I want badVolumeHeaderErr in Errors.i
378 }
379 else
380 {
381 err = noMacDskErr;
382 }
383
384 return( err );
385 }
386
387
388
389
390 //_______________________________________________________________________
391 //
392 // Routine: CountRootFiles
393 //
394 // Input: pointer to VCB
395 //
396 // Function: Return a count of the number of files and folders in
397 // the root directory of a volume. For HFS volumes, this
398 // is maintained in the VCB (and MDB). For HFS Plus volumes,
399 // we get the valence of the root directory from its catalog
400 // record.
401 //_______________________________________________________________________
402 UInt16 CountRootFiles(ExtendedVCB *vcb)
403 {
404 OSErr err;
405 CatalogNodeData catNodeData;
406 UInt32 hint;
407 UInt16 rootCount;
408
409 // if (vcb->vcbSigWord == kHFSSigWord || vcb->vcbFSID != 0) {
410 // return vcb->vcbNmFls;
411 // }
412
413 // Here, it's an HFS Plus volume, so get the valence from the root
414 // directory's catalog record.
415
416 rootCount = 0;
417
418 INIT_CATALOGDATA(&catNodeData, kCatNameNoCopyName);
419
420 err = GetCatalogNode( vcb, kHFSRootFolderID, nil, kUndefinedStrLen, kNoHint, &catNodeData, &hint );
421 if ( err == noErr ) {
422 if (catNodeData.cnd_valence < 65536)
423 rootCount = catNodeData.cnd_valence;
424 else
425 rootCount = 65535; // if the value is too large, pin it
426 }
427 CLEAN_CATALOGDATA(&catNodeData);
428
429 return rootCount;
430 }
431
432
433
434 //_______________________________________________________________________
435 //
436 // Routine: FlushVolumeControlBlock
437 // Arguments: ExtendedVCB *vcb
438 // Output: OSErr err
439 //
440 // Function: Flush volume information to either the VolumeHeader of the Master Directory Block
441 //_______________________________________________________________________
442
443 OSErr FlushVolumeControlBlock( ExtendedVCB *vcb )
444 {
445 OSErr err;
446
447 if ( ! IsVCBDirty( vcb ) ) // if it's not dirty
448 return( noErr );
449
450 if ( vcb->vcbSigWord == kHFSPlusSigWord )
451 {
452 err = C_FlushMDB( vcb ); // Go flush the VCB info BEFORE close
453 }
454 else
455 {
456 // This routine doesn't really return an error!!!
457 // So for now, we will just return noErr
458 err = C_FlushMDB( vcb ); // Go flush the VCB info BEFORE close
459 return( noErr );
460 }
461
462 return( err );
463 }
464
465
466 //\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b\8b
467
468 OSErr GetVolumeNameFromCatalog( ExtendedVCB *vcb )
469 {
470 CatalogNodeData nodeData;
471 UInt32 hint;
472 OSErr err;
473
474 INIT_CATALOGDATA(&nodeData, 0);
475
476 err = GetCatalogNode( vcb, kHFSRootFolderID, NULL, kUndefinedStrLen, kNoHint, &nodeData, &hint );
477
478 if ( err == noErr )
479 {
480 BlockMoveData( nodeData.cnm_nameptr, vcb->vcbVN, min(255, nodeData.cnm_length));
481 vcb->volumeNameEncodingHint = nodeData.cnd_textEncoding;
482
483 /* HFS+ uses the root directory's create date since its in GMT */
484 if (vcb->vcbSigWord == kHFSPlusSigWord)
485 vcb->vcbCrDate = nodeData.cnd_createDate;
486 }
487
488 CLEAN_CATALOGDATA(&nodeData);
489
490 return err;
491 }