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