xref: /AOO41X/main/sot/source/sdstor/stgio.cxx (revision 046d9d1f4a61a93bd4858ca5e371cb4714755d0d)
1*046d9d1fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*046d9d1fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*046d9d1fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*046d9d1fSAndrew Rist  * distributed with this work for additional information
6*046d9d1fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*046d9d1fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*046d9d1fSAndrew Rist  * "License"); you may not use this file except in compliance
9*046d9d1fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*046d9d1fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*046d9d1fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*046d9d1fSAndrew Rist  * software distributed under the License is distributed on an
15*046d9d1fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*046d9d1fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*046d9d1fSAndrew Rist  * specific language governing permissions and limitations
18*046d9d1fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*046d9d1fSAndrew Rist  *************************************************************/
21*046d9d1fSAndrew Rist 
22*046d9d1fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sot.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "sot/stg.hxx"
28cdf0e10cSrcweir #include "stgelem.hxx"
29cdf0e10cSrcweir #include "stgcache.hxx"
30cdf0e10cSrcweir #include "stgstrms.hxx"
31cdf0e10cSrcweir #include "stgdir.hxx"
32cdf0e10cSrcweir #include "stgio.hxx"
33cdf0e10cSrcweir #include <rtl/instance.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir ///////////////////////////// class StgIo //////////////////////////////
36cdf0e10cSrcweir 
37cdf0e10cSrcweir // This class holds the storage header and all internal streams.
38cdf0e10cSrcweir 
39cdf0e10cSrcweir StgIo::StgIo() : StgCache()
40cdf0e10cSrcweir {
41cdf0e10cSrcweir     pTOC      = NULL;
42cdf0e10cSrcweir     pDataFAT  = NULL;
43cdf0e10cSrcweir     pDataStrm = NULL;
44cdf0e10cSrcweir     pFAT      = NULL;
45cdf0e10cSrcweir 	bCopied   = sal_False;
46cdf0e10cSrcweir }
47cdf0e10cSrcweir 
48cdf0e10cSrcweir StgIo::~StgIo()
49cdf0e10cSrcweir {
50cdf0e10cSrcweir     delete pTOC;
51cdf0e10cSrcweir     delete pDataFAT;
52cdf0e10cSrcweir     delete pDataStrm;
53cdf0e10cSrcweir     delete pFAT;
54cdf0e10cSrcweir }
55cdf0e10cSrcweir 
56cdf0e10cSrcweir // Load the header. Do not set an error code if the header is invalid.
57cdf0e10cSrcweir 
58cdf0e10cSrcweir sal_Bool StgIo::Load()
59cdf0e10cSrcweir {
60cdf0e10cSrcweir     if( pStrm )
61cdf0e10cSrcweir     {
62cdf0e10cSrcweir         if( aHdr.Load( *this ) )
63cdf0e10cSrcweir         {
64cdf0e10cSrcweir             if( aHdr.Check() )
65cdf0e10cSrcweir                 SetupStreams();
66cdf0e10cSrcweir             else
67cdf0e10cSrcweir 				return sal_False;
68cdf0e10cSrcweir         }
69cdf0e10cSrcweir     }
70cdf0e10cSrcweir     return Good();
71cdf0e10cSrcweir }
72cdf0e10cSrcweir 
73cdf0e10cSrcweir // Set up an initial, empty storage
74cdf0e10cSrcweir 
75cdf0e10cSrcweir sal_Bool StgIo::Init()
76cdf0e10cSrcweir {
77cdf0e10cSrcweir     aHdr.Init();
78cdf0e10cSrcweir     SetupStreams();
79cdf0e10cSrcweir     return CommitAll();
80cdf0e10cSrcweir }
81cdf0e10cSrcweir 
82cdf0e10cSrcweir void StgIo::SetupStreams()
83cdf0e10cSrcweir {
84cdf0e10cSrcweir     delete pTOC;
85cdf0e10cSrcweir     delete pDataFAT;
86cdf0e10cSrcweir     delete pDataStrm;
87cdf0e10cSrcweir     delete pFAT;
88cdf0e10cSrcweir     pTOC      = NULL;
89cdf0e10cSrcweir     pDataFAT  = NULL;
90cdf0e10cSrcweir     pDataStrm = NULL;
91cdf0e10cSrcweir     pFAT      = NULL;
92cdf0e10cSrcweir     ResetError();
93cdf0e10cSrcweir     SetPhysPageSize( 1 << aHdr.GetPageSize() );
94cdf0e10cSrcweir     pFAT = new StgFATStrm( *this );
95cdf0e10cSrcweir     pTOC = new StgDirStrm( *this );
96cdf0e10cSrcweir 	if( !GetError() )
97cdf0e10cSrcweir 	{
98cdf0e10cSrcweir 		StgDirEntry* pRoot = pTOC->GetRoot();
99cdf0e10cSrcweir 		if( pRoot )
100cdf0e10cSrcweir 		{
101cdf0e10cSrcweir 			pDataFAT = new StgDataStrm( *this, aHdr.GetDataFATStart(), -1 );
102cdf0e10cSrcweir 			pDataStrm = new StgDataStrm( *this, pRoot );
103cdf0e10cSrcweir 			pDataFAT->SetIncrement( 1 << aHdr.GetPageSize() );
104cdf0e10cSrcweir 			pDataStrm->SetIncrement( GetDataPageSize() );
105cdf0e10cSrcweir 			pDataStrm->SetEntry( *pRoot );
106cdf0e10cSrcweir 		}
107cdf0e10cSrcweir 		else
108cdf0e10cSrcweir 			SetError( SVSTREAM_FILEFORMAT_ERROR );
109cdf0e10cSrcweir 	}
110cdf0e10cSrcweir }
111cdf0e10cSrcweir 
112cdf0e10cSrcweir // get the logical data page size
113cdf0e10cSrcweir 
114cdf0e10cSrcweir short StgIo::GetDataPageSize()
115cdf0e10cSrcweir {
116cdf0e10cSrcweir     return 1 << aHdr.GetDataPageSize();
117cdf0e10cSrcweir }
118cdf0e10cSrcweir 
119cdf0e10cSrcweir // Commit everything
120cdf0e10cSrcweir 
121cdf0e10cSrcweir sal_Bool StgIo::CommitAll()
122cdf0e10cSrcweir {
123cdf0e10cSrcweir 	// Store the data (all streams and the TOC)
124cdf0e10cSrcweir     if( pTOC->Store() )
125cdf0e10cSrcweir     {
126cdf0e10cSrcweir         if( Commit( NULL ) )
127cdf0e10cSrcweir         {
128cdf0e10cSrcweir             aHdr.SetDataFATStart( pDataFAT->GetStart() );
129cdf0e10cSrcweir             aHdr.SetDataFATSize( pDataFAT->GetPages() );
130cdf0e10cSrcweir             aHdr.SetTOCStart( pTOC->GetStart() );
131cdf0e10cSrcweir             if( aHdr.Store( *this ) )
132cdf0e10cSrcweir 			{
133cdf0e10cSrcweir 				pStrm->Flush();
134cdf0e10cSrcweir 				sal_uLong n = pStrm->GetError();
135cdf0e10cSrcweir 				SetError( n );
136cdf0e10cSrcweir #ifdef DBG_UTIL
137cdf0e10cSrcweir 				if( n==0 ) ValidateFATs();
138cdf0e10cSrcweir #endif
139cdf0e10cSrcweir 				return sal_Bool( n == 0 );
140cdf0e10cSrcweir 			}
141cdf0e10cSrcweir         }
142cdf0e10cSrcweir     }
143cdf0e10cSrcweir 	SetError( SVSTREAM_WRITE_ERROR );
144cdf0e10cSrcweir 	return sal_False;
145cdf0e10cSrcweir }
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 
148cdf0e10cSrcweir class EasyFat
149cdf0e10cSrcweir {
150cdf0e10cSrcweir 	sal_Int32 *pFat;
151cdf0e10cSrcweir 	sal_Bool  *pFree;
152cdf0e10cSrcweir 	sal_Int32 nPages;
153cdf0e10cSrcweir 	sal_Int32 nPageSize;
154cdf0e10cSrcweir 
155cdf0e10cSrcweir public:
156cdf0e10cSrcweir 	EasyFat( StgIo & rIo, StgStrm *pFatStream, sal_Int32 nPSize );
157cdf0e10cSrcweir 	~EasyFat() { delete[] pFat; delete[] pFree; }
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 	sal_Int32 GetPageSize() { return nPageSize; }
160cdf0e10cSrcweir 	sal_Int32 Count() { return nPages; }
161cdf0e10cSrcweir 	sal_Int32 operator[]( sal_Int32 nOffset ) { return pFat[ nOffset ]; }
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 	sal_uLong Mark( sal_Int32 nPage, sal_Int32 nCount, sal_Int32 nExpect );
164cdf0e10cSrcweir 	sal_Bool HasUnrefChains();
165cdf0e10cSrcweir };
166cdf0e10cSrcweir 
167cdf0e10cSrcweir EasyFat::EasyFat( StgIo& rIo, StgStrm* pFatStream, sal_Int32 nPSize )
168cdf0e10cSrcweir {
169cdf0e10cSrcweir 	nPages = pFatStream->GetSize() >> 2;
170cdf0e10cSrcweir 	nPageSize = nPSize;
171cdf0e10cSrcweir 	pFat = new sal_Int32[ nPages ];
172cdf0e10cSrcweir 	pFree = new sal_Bool[ nPages ];
173cdf0e10cSrcweir 
174cdf0e10cSrcweir 	StgPage *pPage = NULL;
175cdf0e10cSrcweir 	sal_Int32 nFatPageSize = (1 << rIo.aHdr.GetPageSize()) - 2;
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 	for( sal_Int32 nPage = 0; nPage < nPages; nPage++ )
178cdf0e10cSrcweir 	{
179cdf0e10cSrcweir 		if( ! (nPage % nFatPageSize) )
180cdf0e10cSrcweir 		{
181cdf0e10cSrcweir 			pFatStream->Pos2Page( nPage << 2 );
182cdf0e10cSrcweir 			sal_Int32 nPhysPage = pFatStream->GetPage();
183cdf0e10cSrcweir 			pPage = rIo.Get( nPhysPage, sal_True );
184cdf0e10cSrcweir 		}
185cdf0e10cSrcweir 
186cdf0e10cSrcweir 		pFat[ nPage ] = pPage->GetPage( short( nPage % nFatPageSize ) );
187cdf0e10cSrcweir 		pFree[ nPage ] = sal_True;
188cdf0e10cSrcweir 	}
189cdf0e10cSrcweir }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir sal_Bool EasyFat::HasUnrefChains()
192cdf0e10cSrcweir {
193cdf0e10cSrcweir 	for( sal_Int32 nPage = 0; nPage < nPages; nPage++ )
194cdf0e10cSrcweir 	{
195cdf0e10cSrcweir 		if( pFree[ nPage ] && pFat[ nPage ] != -1 )
196cdf0e10cSrcweir 			return sal_True;
197cdf0e10cSrcweir 	}
198cdf0e10cSrcweir 	return sal_False;
199cdf0e10cSrcweir }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir sal_uLong EasyFat::Mark( sal_Int32 nPage, sal_Int32 nCount, sal_Int32 nExpect )
202cdf0e10cSrcweir {
203cdf0e10cSrcweir 	if( nCount > 0 )
204cdf0e10cSrcweir 		--nCount /= GetPageSize(), nCount++;
205cdf0e10cSrcweir 
206cdf0e10cSrcweir 	sal_Int32 nCurPage = nPage;
207cdf0e10cSrcweir 	while( nCount != 0 )
208cdf0e10cSrcweir 	{
209cdf0e10cSrcweir 		pFree[ nCurPage ] = sal_False;
210cdf0e10cSrcweir 		nCurPage = pFat[ nCurPage ];
211cdf0e10cSrcweir 		//Stream zu lang
212cdf0e10cSrcweir 		if( nCurPage != nExpect && nCount == 1 )
213cdf0e10cSrcweir 			return FAT_WRONGLENGTH;
214cdf0e10cSrcweir         //Stream zu kurz
215cdf0e10cSrcweir 		if( nCurPage == nExpect && nCount != 1 && nCount != -1 )
216cdf0e10cSrcweir 			return FAT_WRONGLENGTH;
217cdf0e10cSrcweir 		// letzter Block bei Stream ohne Laenge
218cdf0e10cSrcweir 		if( nCurPage == nExpect && nCount == -1 )
219cdf0e10cSrcweir 			nCount = 1;
220cdf0e10cSrcweir 		if( nCount != -1 )
221cdf0e10cSrcweir 			nCount--;
222cdf0e10cSrcweir 		// Naechster Block nicht in der FAT
223cdf0e10cSrcweir 		if( nCount && ( nCurPage < 0 || nCurPage >= nPages ) )
224cdf0e10cSrcweir 			return FAT_OUTOFBOUNDS;
225cdf0e10cSrcweir 	}
226cdf0e10cSrcweir 	return FAT_OK;
227cdf0e10cSrcweir }
228cdf0e10cSrcweir 
229cdf0e10cSrcweir class Validator
230cdf0e10cSrcweir {
231cdf0e10cSrcweir 	sal_uLong nError;
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 	EasyFat aSmallFat;
234cdf0e10cSrcweir 	EasyFat aFat;
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 	StgIo &rIo;
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 	sal_uLong ValidateMasterFATs();
239cdf0e10cSrcweir 	sal_uLong ValidateDirectoryEntries();
240cdf0e10cSrcweir 	sal_uLong FindUnrefedChains();
241cdf0e10cSrcweir 	sal_uLong MarkAll( StgDirEntry *pEntry );
242cdf0e10cSrcweir 
243cdf0e10cSrcweir public:
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 	Validator( StgIo &rIo );
246cdf0e10cSrcweir 	sal_Bool IsError() { return nError != 0; }
247cdf0e10cSrcweir };
248cdf0e10cSrcweir 
249cdf0e10cSrcweir Validator::Validator( StgIo &rIoP )
250cdf0e10cSrcweir 	: aSmallFat( rIoP, rIoP.pDataFAT, 1 << rIoP.aHdr.GetDataPageSize() ),
251cdf0e10cSrcweir 	  aFat( rIoP, rIoP.pFAT, 1 << rIoP.aHdr.GetPageSize() ),
252cdf0e10cSrcweir 	  rIo( rIoP )
253cdf0e10cSrcweir {
254cdf0e10cSrcweir 	sal_uLong nErr = nError = FAT_OK;
255cdf0e10cSrcweir 
256cdf0e10cSrcweir 	if(	( nErr = ValidateMasterFATs() ) != FAT_OK )
257cdf0e10cSrcweir 		nError = nErr;
258cdf0e10cSrcweir 	else if(	( nErr = ValidateDirectoryEntries() ) != FAT_OK )
259cdf0e10cSrcweir 		nError = nErr;
260cdf0e10cSrcweir 	else if(	( nErr = FindUnrefedChains()) != FAT_OK )
261cdf0e10cSrcweir 		nError = nErr;
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir sal_uLong Validator::ValidateMasterFATs()
265cdf0e10cSrcweir {
266cdf0e10cSrcweir     sal_Int32 nCount = rIo.aHdr.GetFATSize();
267cdf0e10cSrcweir     sal_uLong nErr;
268cdf0e10cSrcweir     for( sal_Int32 i = 0; i < nCount; i++ )
269cdf0e10cSrcweir     {
270cdf0e10cSrcweir         if( ( nErr = aFat.Mark(rIo.pFAT->GetPage( short(i), sal_False ), aFat.GetPageSize(), -3 )) != FAT_OK )
271cdf0e10cSrcweir             return nErr;
272cdf0e10cSrcweir     }
273cdf0e10cSrcweir     if( rIo.aHdr.GetMasters() )
274cdf0e10cSrcweir         if( ( nErr = aFat.Mark(rIo.aHdr.GetFATChain( ), aFat.GetPageSize(), -4 )) != FAT_OK )
275cdf0e10cSrcweir             return nErr;
276cdf0e10cSrcweir     return FAT_OK;
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
279cdf0e10cSrcweir sal_uLong Validator::MarkAll( StgDirEntry *pEntry )
280cdf0e10cSrcweir {
281cdf0e10cSrcweir 	StgIterator aIter( *pEntry );
282cdf0e10cSrcweir 	sal_uLong nErr = FAT_OK;
283cdf0e10cSrcweir 	for( StgDirEntry* p = aIter.First(); p ; p = aIter.Next() )
284cdf0e10cSrcweir 	{
285cdf0e10cSrcweir 		if( p->aEntry.GetType() == STG_STORAGE )
286cdf0e10cSrcweir 		{
287cdf0e10cSrcweir 			nErr = MarkAll( p );
288cdf0e10cSrcweir 			if( nErr != FAT_OK )
289cdf0e10cSrcweir 				return nErr;
290cdf0e10cSrcweir 		}
291cdf0e10cSrcweir 		else
292cdf0e10cSrcweir 		{
293cdf0e10cSrcweir 			sal_Int32 nSize = p->aEntry.GetSize();
294cdf0e10cSrcweir 			if( nSize < rIo.aHdr.GetThreshold()  )
295cdf0e10cSrcweir 				nErr = aSmallFat.Mark( p->aEntry.GetStartPage(),nSize, -2 );
296cdf0e10cSrcweir 			else
297cdf0e10cSrcweir 				nErr = aFat.Mark( p->aEntry.GetStartPage(),nSize, -2 );
298cdf0e10cSrcweir 			if( nErr != FAT_OK )
299cdf0e10cSrcweir 				return nErr;
300cdf0e10cSrcweir 		}
301cdf0e10cSrcweir 	}
302cdf0e10cSrcweir 	return FAT_OK;
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir sal_uLong Validator::ValidateDirectoryEntries()
306cdf0e10cSrcweir {
307cdf0e10cSrcweir 	// Normale DirEntries
308cdf0e10cSrcweir 	sal_uLong nErr = MarkAll( rIo.pTOC->GetRoot() );
309cdf0e10cSrcweir 	if( nErr != FAT_OK )
310cdf0e10cSrcweir 		return nErr;
311cdf0e10cSrcweir 	// Small Data
312cdf0e10cSrcweir 	nErr = aFat.Mark( rIo.pTOC->GetRoot()->aEntry.GetStartPage(),
313cdf0e10cSrcweir 				 rIo.pTOC->GetRoot()->aEntry.GetSize(), -2 );
314cdf0e10cSrcweir 	if( nErr != FAT_OK )
315cdf0e10cSrcweir 		return nErr;
316cdf0e10cSrcweir 	// Small Data FAT
317cdf0e10cSrcweir 	nErr = aFat.Mark(
318cdf0e10cSrcweir 		rIo.aHdr.GetDataFATStart(),
319cdf0e10cSrcweir 		rIo.aHdr.GetDataFATSize() * aFat.GetPageSize(), -2 );
320cdf0e10cSrcweir 	if( nErr != FAT_OK )
321cdf0e10cSrcweir 		return nErr;
322cdf0e10cSrcweir 	// TOC
323cdf0e10cSrcweir 	nErr = aFat.Mark(
324cdf0e10cSrcweir 		rIo.aHdr.GetTOCStart(),	-1, -2 );
325cdf0e10cSrcweir 	return nErr;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir sal_uLong Validator::FindUnrefedChains()
329cdf0e10cSrcweir {
330cdf0e10cSrcweir 	if( aSmallFat.HasUnrefChains() ||
331cdf0e10cSrcweir 		aFat.HasUnrefChains() )
332cdf0e10cSrcweir 		return FAT_UNREFCHAIN;
333cdf0e10cSrcweir 	else
334cdf0e10cSrcweir 		return FAT_OK;
335cdf0e10cSrcweir }
336cdf0e10cSrcweir 
337cdf0e10cSrcweir namespace { struct ErrorLink : public rtl::Static<Link, ErrorLink > {}; }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir void StgIo::SetErrorLink( const Link& rLink )
340cdf0e10cSrcweir {
341cdf0e10cSrcweir 	ErrorLink::get() = rLink;
342cdf0e10cSrcweir }
343cdf0e10cSrcweir 
344cdf0e10cSrcweir const Link& StgIo::GetErrorLink()
345cdf0e10cSrcweir {
346cdf0e10cSrcweir     return ErrorLink::get();
347cdf0e10cSrcweir }
348cdf0e10cSrcweir 
349cdf0e10cSrcweir sal_uLong StgIo::ValidateFATs()
350cdf0e10cSrcweir {
351cdf0e10cSrcweir 	if( bFile )
352cdf0e10cSrcweir 	{
353cdf0e10cSrcweir 		Validator *pV = new Validator( *this );
354cdf0e10cSrcweir 		sal_Bool bRet1 = !pV->IsError(), bRet2 = sal_True ;
355cdf0e10cSrcweir 		delete pV;
356cdf0e10cSrcweir 		SvFileStream *pFileStrm = ( SvFileStream *) GetStrm();
357cdf0e10cSrcweir 		StgIo aIo;
358cdf0e10cSrcweir 		if( aIo.Open( pFileStrm->GetFileName(),
359cdf0e10cSrcweir 					  STREAM_READ  | STREAM_SHARE_DENYNONE) &&
360cdf0e10cSrcweir 			aIo.Load() )
361cdf0e10cSrcweir 		{
362cdf0e10cSrcweir 			pV = new Validator( aIo );
363cdf0e10cSrcweir 			bRet2 = !pV->IsError();
364cdf0e10cSrcweir 			delete pV;
365cdf0e10cSrcweir 		}
366cdf0e10cSrcweir 
367cdf0e10cSrcweir 		sal_uLong nErr;
368cdf0e10cSrcweir 		if( bRet1 != bRet2 )
369cdf0e10cSrcweir 			nErr = bRet1 ? FAT_ONFILEERROR : FAT_INMEMORYERROR;
370cdf0e10cSrcweir 		else nErr = bRet1 ? FAT_OK : FAT_BOTHERROR;
371cdf0e10cSrcweir 		if( nErr != FAT_OK && !bCopied )
372cdf0e10cSrcweir 		{
373cdf0e10cSrcweir 			StgLinkArg aArg;
374cdf0e10cSrcweir 			aArg.aFile = pFileStrm->GetFileName();
375cdf0e10cSrcweir 			aArg.nErr = nErr;
376cdf0e10cSrcweir 			ErrorLink::get().Call( &aArg );
377cdf0e10cSrcweir 			bCopied = sal_True;
378cdf0e10cSrcweir 		}
379cdf0e10cSrcweir //		DBG_ASSERT( nErr == FAT_OK ,"Storage kaputt");
380cdf0e10cSrcweir 		return nErr;
381cdf0e10cSrcweir 	}
382cdf0e10cSrcweir //	DBG_ERROR("Validiere nicht (kein FileStorage)");
383cdf0e10cSrcweir 	return FAT_OK;
384cdf0e10cSrcweir }
385