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