ReactOS 0.4.16-dev-336-gb667d82
mount.cpp
Go to the documentation of this file.
1
2// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3// All rights reserved
4// This file was released under the GPLv2 on June 2015.
6/*
7 Module name:
8
9 mount.cpp
10
11 Abstract:
12
13 This file contains filesystem-specific routines
14 responsible for Mount/Umount
15
16*/
17
18#include "udf.h"
19
20/* FIXME */
21#ifdef XCHG_DD
22#undef XCHG_DD
23#endif
24
25#define XCHG_DD(a,b) \
26{ \
27 ULONG _temp_; \
28 PULONG _from_, _to_; \
29 _from_ = ((PULONG)&(b)); \
30 _to_ = ((PULONG)&(a)); \
31 _temp_ = *_from_; \
32 *_from_ = *_to_; \
33 *_to_ = _temp_; \
34}
35
36#define UDF_BUG_CHECK_ID UDF_FILE_UDF_INFO_MOUNT
37
41 IN PUNICODE_STRING UName,
42 IN dstring* Dest,
44 );
45
46#ifndef UDF_READ_ONLY_BUILD
47/*
48 This routine loads specified bitmap.
49 It is also allocate space if the bitmap is not allocated.
50 */
53 IN PVCB Vcb,
54 IN OUT PSHORT_AD XSpaceBitmap,
55 IN OUT PEXTENT_INFO XSBMExtInfo,
56 IN OUT int8** XSBM,
57 IN OUT uint32* XSl
58 )
59{
60 uint32 BS, j, LBS;
61 uint32 plen;
63 EXTENT_MAP TmpExt;
64 lb_addr locAddr;
65 int8* _XSBM;
66 uint16 Ident;
68 uint32 PartNum;
69
70 if(!(XSpaceBitmap->extLength)) {
71 *XSl = 0;
72 *XSBM = NULL;
73 return STATUS_SUCCESS;
74 }
75
76 PartNum = UDFGetPartNumByPartNdx(Vcb, Vcb->PartitionMaps-1);
77 locAddr.partitionReferenceNum = (uint16)PartNum;
78 plen = UDFPartStart(Vcb, PartNum) + UDFPartLen(Vcb, PartNum);
79
80 BS = Vcb->BlockSize;
81 LBS = Vcb->LBlockSize;
82
83 *XSl = sizeof(SPACE_BITMAP_DESC) + ((plen+7)>>3);
84 _XSBM = (int8*)DbgAllocatePool(NonPagedPool, (*XSl + BS - 1) & ~(BS-1) );
85 *XSBM = _XSBM;
86
87 switch (XSpaceBitmap->extLength >> 30) {
89 locAddr.logicalBlockNum = XSpaceBitmap->extPosition;
90 *XSl = min(XSpaceBitmap->extLength, *XSl);
91 TmpExt.extLength = XSpaceBitmap->extLength = *XSl;
92 TmpExt.extLocation = UDFPartLbaToPhys(Vcb, &locAddr);
93 if(TmpExt.extLocation == LBA_OUT_OF_EXTENT) {
94 BrutePoint();
95 }
96 XSBMExtInfo->Mapping = UDFExtentToMapping(&TmpExt);
97 XSBMExtInfo->Offset = 0;
98 XSBMExtInfo->Length = *XSl;
99 break;
100 }
103 // allocate space for bitmap
105 UDFPartStart(Vcb, PartNum), UDFPartEnd(Vcb, PartNum), XSBMExtInfo, EXTENT_FLAG_ALLOC_SEQUENTIAL) ))
106 return status;
107 if(XSBMExtInfo->Mapping[1].extLength) {
108 UDFPrint(("Can't allocate space for Freed Space bitmap\n"));
109 *XSl = 0;
110 } else {
111 *XSl = (uint32)(XSBMExtInfo->Length);
112 XSpaceBitmap->extPosition = UDFPhysLbaToPart(Vcb, PartNum, XSBMExtInfo->Mapping[0].extLocation);
113 }
114 break;
115 }
117 // record Alloc-Not-Rec
118 locAddr.logicalBlockNum = XSpaceBitmap->extPosition;
119 *XSl = min((XSpaceBitmap->extLength & UDF_EXTENT_LENGTH_MASK), *XSl);
120 TmpExt.extLength = XSpaceBitmap->extLength = *XSl;
121 TmpExt.extLocation = UDFPartLbaToPhys(Vcb, &locAddr);
122 if(TmpExt.extLocation == LBA_OUT_OF_EXTENT) {
123 BrutePoint();
124 }
125 XSBMExtInfo->Mapping = UDFExtentToMapping(&TmpExt);
126 XSBMExtInfo->Offset = 0;
127 XSBMExtInfo->Length = *XSl;
128 break;
129 }
130 }
131
132 if(!_XSBM) {
133 BrutePoint();
135 }
136
137 switch (XSpaceBitmap->extLength >> 30) {
139 // read descriptor & bitmap
140 if((!OS_SUCCESS(status = UDFReadTagged(Vcb, *XSBM, (j = TmpExt.extLocation),
141 locAddr.logicalBlockNum, &Ident))) ||
142 (Ident != TID_SPACE_BITMAP_DESC) ||
143 (!OS_SUCCESS(status = UDFReadExtent(Vcb, XSBMExtInfo, 0, *XSl, FALSE, *XSBM, &ReadBytes))) ) {
144 if(OS_SUCCESS(status)) {
145 BrutePoint();
147 }
148 if(XSBMExtInfo->Mapping) {
149 MyFreePool__(XSBMExtInfo->Mapping);
150 XSBMExtInfo->Mapping = NULL;
151 }
152 DbgFreePool(*XSBM);
153 *XSl = 0;
154 *XSBM = NULL;
155 return status;
156 } else {
157// BrutePoint();
158 }
159 return STATUS_SUCCESS;
160 }
161#if 0
165 break;
166 }
167#endif
168 }
169
170 PSPACE_BITMAP_DESC XSDesc = (PSPACE_BITMAP_DESC)(*XSBM);
171
172 XSpaceBitmap->extLength = (*XSl + LBS -1) & ~(LBS-1);
173 RtlZeroMemory(*XSBM, *XSl);
175 UDFSetUpTag(Vcb, &(XSDesc->descTag), 0, XSpaceBitmap->extPosition);
176 XSDesc->numOfBits = plen;
177 XSDesc->numOfBytes = (*XSl)-sizeof(SPACE_BITMAP_DESC);
178
179 return STATUS_SUCCESS;
180} // end UDFPrepareXSpaceBitmap()
181
182/*
183 This routine updates Freed & Unallocated space bitmaps
184 */
187 IN PVCB Vcb,
188 IN uint32 PartNum,
189 IN PPARTITION_HEADER_DESC phd // partition header pointing to Bitmaps
190 )
191{
192 uint32 i,j,d;
193 uint32 plen, pstart, pend;
194 int8* bad_bm;
195 int8* old_bm;
196 int8* new_bm;
197 int8* fpart_bm;
198 int8* upart_bm;
199 OSSTATUS status, status2;
200 int8* USBM=NULL;
201 int8* FSBM=NULL;
202 uint32 USl, FSl;
203 EXTENT_INFO FSBMExtInfo, USBMExtInfo;
204// lb_addr locAddr;
205 SIZE_T WrittenBytes;
206
208
209 plen = UDFPartLen(Vcb, PartNum);
210// locAddr.partitionReferenceNum = (uint16)PartNum;
211 // prepare bitmaps for updating
212
213 status = UDFPrepareXSpaceBitmap(Vcb, &(phd->unallocatedSpaceBitmap), &USBMExtInfo, &USBM, &USl);
214 status2 = UDFPrepareXSpaceBitmap(Vcb, &(phd->freedSpaceBitmap), &FSBMExtInfo, &FSBM, &FSl);
215 if(!OS_SUCCESS(status) ||
216 !OS_SUCCESS(status2)) {
217 BrutePoint();
218 }
219
220 pstart = UDFPartStart(Vcb, PartNum);
221 new_bm = Vcb->FSBM_Bitmap;
222 old_bm = Vcb->FSBM_OldBitmap;
223 bad_bm = Vcb->BSBM_Bitmap;
224
226 (status2 == STATUS_INSUFFICIENT_RESOURCES)) {
227 // try to recover insufficient resources
228 if(USl && USBMExtInfo.Mapping) {
229 USl -= sizeof(SPACE_BITMAP_DESC);
230 status = UDFWriteExtent(Vcb, &USBMExtInfo, sizeof(SPACE_BITMAP_DESC), USl, FALSE, new_bm, &WrittenBytes);
231#ifdef UDF_DBG
232 } else {
233 UDFPrint(("Can't update USBM\n"));
234#endif // UDF_DBG
235 }
236 if(USBMExtInfo.Mapping) MyFreePool__(USBMExtInfo.Mapping);
237
238 if(FSl && FSBMExtInfo.Mapping) {
239 FSl -= sizeof(SPACE_BITMAP_DESC);
240 status2 = UDFWriteExtent(Vcb, &FSBMExtInfo, sizeof(SPACE_BITMAP_DESC), FSl, FALSE, new_bm, &WrittenBytes);
241 } else {
242 status2 = status;
243 UDFPrint(("Can't update FSBM\n"));
244 }
245 if(FSBMExtInfo.Mapping) MyFreePool__(FSBMExtInfo.Mapping);
246 } else {
247 // normal way to record BitMaps
248 if(USBM) upart_bm = USBM + sizeof(SPACE_BITMAP_DESC);
249 if(FSBM) fpart_bm = FSBM + sizeof(SPACE_BITMAP_DESC);
250 pend = min(pstart + plen, Vcb->FSBM_BitCount);
251
252 d=1<<Vcb->LB2B_Bits;
253 // if we have some bad bits, mark corresponding area as BAD
254 if(bad_bm) {
255 for(i=pstart; i<pend; i++) {
256 if(UDFGetBadBit(bad_bm, i)) {
257 // TODO: would be nice to add these blocks to unallocatable space
258 UDFSetUsedBits(new_bm, i & ~(d-1), d);
259 }
260 }
261 }
262 j=0;
263 for(i=pstart; i<pend; i+=d) {
264 if(UDFGetUsedBit(old_bm, i) && UDFGetFreeBit(new_bm, i)) {
265 // sector was deallocated during last session
266 if(USBM) UDFSetFreeBit(upart_bm, j);
267 if(FSBM) UDFSetFreeBit(fpart_bm, j);
268 } else if(UDFGetUsedBit(new_bm, i)) {
269 // allocated
270 if(USBM) UDFSetUsedBit(upart_bm, j);
271 if(FSBM) UDFSetUsedBit(fpart_bm, j);
272 }
273 j++;
274 }
275 // flush updates
276 if(USBM) {
277 status = UDFWriteExtent(Vcb, &USBMExtInfo, 0, USl, FALSE, USBM, &WrittenBytes);
278 DbgFreePool(USBM);
279 MyFreePool__(USBMExtInfo.Mapping);
280 }
281 if(FSBM) {
282 status2 = UDFWriteExtent(Vcb, &FSBMExtInfo, 0, FSl, FALSE, FSBM, &WrittenBytes);
283 DbgFreePool(FSBM);
284 MyFreePool__(FSBMExtInfo.Mapping);
285 } else {
286 status2 = status;
287 }
288 }
289
290 if(!OS_SUCCESS(status))
291 return status;
292 return status2;
293} // end UDFUpdateXSpaceBitmaps()
294
295/*
296 This routine updates Partition Desc & associated data structures
297 */
300 PVCB Vcb,
301 int8* Buf
302 )
303{
304 PartitionDesc *p = (PartitionDesc *)Buf;
305 uint32 i; // PartNdx
306 tag* PTag;
307 SIZE_T WrittenBytes;
308
309 for(i=0; i<Vcb->PartitionMaps; i++)
310 {
311 if((UDFGetPartNumByPartNdx(Vcb,i) == p->partitionNumber) &&
312 (!strcmp((int8*)&(p->partitionContents.ident), PARTITION_CONTENTS_NSR02) ||
313 !strcmp((int8*)&(p->partitionContents.ident), PARTITION_CONTENTS_NSR03)))
314 {
316
317 phd = (PPARTITION_HEADER_DESC)(p->partitionContentsUse);
318#ifdef UDF_DBG
320 // rebuild unallocatedSpaceTable
321 UDFPrint(("unallocatedSpaceTable (part %d)\n", i));
322 }
323 if(phd->freedSpaceTable.extLength) {
324 // rebuild freedSpaceTable
325 UDFPrint(("freedSpaceTable (part %d)\n", i));
326 }
327#endif // UDF_DBG
328 UDFUpdateXSpaceBitmaps(Vcb, p->partitionNumber, phd);
329 PTag = (tag*)Buf;
330 UDFSetUpTag(Vcb, PTag, PTag->descCRCLength, PTag->tagLocation);
331 UDFWriteSectors(Vcb, TRUE, PTag->tagLocation, 1, FALSE, Buf, &WrittenBytes);
332 }
333 }
334 return STATUS_SUCCESS;
335} // end UDFUpdatePartDesc()
336
337/*
338 This routine blanks Unalloc Space Desc
339 *//*
340OSSTATUS
341UDFUpdateUSpaceDesc(
342 IN PVCB Vcb,
343 int8* Buf
344 )
345{
346 PUNALLOC_SPACE_DESC usd;
347 SIZE_T WrittenBytes;
348
349 usd = (PUNALLOC_SPACE_DESC)Buf;
350 usd->numAllocDescs = 0;
351 RtlZeroMemory(Buf+sizeof(UNALLOC_SPACE_DESC), Vcb->BlockSize - sizeof(UNALLOC_SPACE_DESC));
352 UDFSetUpTag(Vcb, &(usd->descTag), 0, usd->descTag.tagLocation);
353 UDFWriteSectors(Vcb, TRUE, usd->descTag.tagLocation, 1, FALSE, Buf, &WrittenBytes);
354 return STATUS_SUCCESS;
355}*/
356
357/*
358 update Logical volume integrity descriptor
359 */
362 PVCB Vcb,
364 )
365{
367 uint32 i, len;
368 SIZE_T WrittenBytes;
369// uint32 lvid_count = 0;
370 uint32 pSize;
371 tag* PTag;
374 LogicalVolHeaderDesc* LVID_hd;
375 uint32* partFreeSpace;
377
378 if(Vcb->CDR_Mode)
379 return STATUS_SUCCESS;
380 if(!Vcb->LVid) {
381 return STATUS_UNSUCCESSFUL;
382 }
383
384 UDFPrint(("UDF: Updating LVID @%x (%x)\n", Vcb->LVid_loc.extLocation, Vcb->LVid_loc.extLength));
385 len = max(Vcb->LVid_loc.extLength, Vcb->BlockSize);
386 lvid = Vcb->LVid;
387 if(lvid->descTag.tagSerialNum > UDF_LVID_TTL) {
388 // TODO: allocate space for new LVID
389 }
390
391 LVID_iUse = UDFGetLVIDiUse(Vcb);
392
393 if((LVID_iUse->minUDFReadRev == Vcb->minUDFReadRev) &&
394 (LVID_iUse->minUDFWriteRev == Vcb->minUDFWriteRev) &&
395 (LVID_iUse->maxUDFWriteRev == Vcb->maxUDFWriteRev) &&
396 (LVID_iUse->numFiles == Vcb->numFiles) &&
397 (LVID_iUse->numDirs == Vcb->numDirs))
398 equal = TRUE;
399
400 LVID_iUse->minUDFReadRev = Vcb->minUDFReadRev;
401 LVID_iUse->minUDFWriteRev = Vcb->minUDFWriteRev;
402 LVID_iUse->maxUDFWriteRev = Vcb->maxUDFWriteRev;
403
404 LVID_iUse->numFiles = Vcb->numFiles;
405 LVID_iUse->numDirs = Vcb->numDirs;
406
407#if 0
409#endif
410
411 if(Close){
412 UDFPrint(("UDF: Opening LVID\n"));
414 } else {
415 UDFPrint(("UDF: Closing LVID\n"));
417 }
418
419 equal = equal && (Vcb->IntegrityType == lvid->integrityType);
420
421 // update Free Space Table
422 partFreeSpace = (uint32*)(lvid+1);
423 for(i=0; i<lvid->numOfPartitions; i++) {
424 pSize = UDFGetPartFreeSpace(Vcb, i) >> Vcb->LB2B_Bits;
425 equal = equal && (partFreeSpace[i] == pSize);
426 partFreeSpace[i] = pSize;
427 }
428
429 // Update LVID Header Descriptor
430 LVID_hd = (LogicalVolHeaderDesc*)&(lvid->logicalVolContentsUse);
431 equal = equal && (LVID_hd->uniqueID == Vcb->NextUniqueId);
432 LVID_hd->uniqueID = Vcb->NextUniqueId;
433
434 if(equal) {
435 UDFPrint(("UDF: equal Ids\n"));
436 return STATUS_SUCCESS;
437 }
438
439 PTag = &(lvid->descTag);
440 lvid->lengthOfImpUse =
442 UDFSetUpTag(Vcb, PTag,
444 sizeof(uint32)*2*lvid->numOfPartitions +
446 PTag->tagLocation);
447
448 Vcb->IntegrityType = INTEGRITY_TYPE_OPEN; // make happy auto-dirty
449 RC = UDFWriteSectors(Vcb, TRUE, PTag->tagLocation, len >> Vcb->BlockSizeBits, FALSE, (int8*)(lvid), &WrittenBytes);
450 WCacheFlushBlocks__(&(Vcb->FastCache), Vcb, PTag->tagLocation, len >> Vcb->BlockSizeBits);
451 // update it here to prevent recursion
452 Vcb->IntegrityType = lvid->integrityType;
453
454 return RC;
455} // end UDFUpdateLogicalVolInt()
456
457/*
458 This routine reads all sparing tables & stores them in contiguos memory
459 space
460 */
463 IN PVCB Vcb
464 )
465{
466 PSPARING_MAP RelocMap;
467// PSPARING_MAP NewRelocMap;
469 OSSTATUS status2 = STATUS_SUCCESS;
470 uint32 i=0, BC, BC2;
471 PSPARING_TABLE SparTable;
473// uint32 n,m;
474// BOOLEAN merged;
475 BOOLEAN sorted;
476
477 UDFPrint(("UDF: Updating Sparable Part Map:\n"));
478 if(!Vcb->SparingTableModified) return STATUS_SUCCESS;
479 if(!Vcb->SparingTable) return STATUS_SUCCESS;
480
481 BC = (Vcb->SparingTableLength >> Vcb->BlockSizeBits) + 1;
482 SparTable = (PSPARING_TABLE)MyAllocatePool__(NonPagedPool, BC*Vcb->BlockSize);
483 if(!SparTable) return STATUS_INSUFFICIENT_RESOURCES;
484 // if a part of Sparing Table is already loaded,
485 // update it with data from another one
486 RelocMap = Vcb->SparingTable;
487 // sort sparing table
488 //merged = FALSE;
489 do {
490 sorted = FALSE;
491 for(i=1;i<Vcb->SparingCount;i++) {
492 if(RelocMap[i-1].origLocation > RelocMap[i].origLocation) {
493 XCHG_DD(RelocMap[i-1].origLocation, RelocMap[i].origLocation);
494swp_loc:
495 XCHG_DD(RelocMap[i-1].mappedLocation, RelocMap[i].mappedLocation);
496 //merged = TRUE;
497 sorted = TRUE;
498 } else
499 if(RelocMap[i-1].origLocation == SPARING_LOC_AVAILABLE &&
500 RelocMap[i].origLocation == SPARING_LOC_AVAILABLE &&
501 RelocMap[i-1].mappedLocation > RelocMap[i].mappedLocation) {
502 goto swp_loc;
503 }
504 }
505 } while(sorted);
506
507 for(i=0;i<Vcb->SparingCount;i++) {
508 UDFPrint((" @%x -> %x \n",
509 RelocMap[i].origLocation, RelocMap[i].mappedLocation));
510 }
511
512 Vcb->SparingTableModified = FALSE;
513// if(!merged) {
514// UDFPrint((" sparing table unchanged\n"));
515// MyFreePool__(SparTable);
516// return STATUS_SUCCESS;
517// }
518
519 // walk through all available Sparing Tables
520 for(i=0;i<Vcb->SparingTableCount;i++) {
521 // read (next) table
522 UDFPrint((" sparing table @%x\n", Vcb->SparingTableLoc[i]));
523 status = UDFReadSectors(Vcb, FALSE, Vcb->SparingTableLoc[i], 1, FALSE, (int8*)SparTable, &ReadBytes);
524 // tag should be set to TID_UNUSED_DESC
525 if(OS_SUCCESS(status) && (SparTable->descTag.tagIdent == TID_UNUSED_DESC)) {
526
527 BC2 = ((sizeof(SPARING_TABLE) +
528 SparTable->reallocationTableLen*sizeof(SparingEntry) +
529 Vcb->BlockSize-1)
530 >> Vcb->BlockSizeBits);
531 if(BC2 > BC) {
532 UDFPrint((" sizeSparingTable @%x too long: %x > %x\n",
533 Vcb->SparingTableLoc[i], BC2, BC
534 ));
535 continue;
536 }
537 status = UDFReadSectors(Vcb, FALSE, Vcb->SparingTableLoc[i],
538 BC2, FALSE, (int8*)SparTable, &ReadBytes);
539
540 if(!OS_SUCCESS(status)) {
541 UDFPrint((" Error reading sizeSparingTable @%x (%x)\n",
542 Vcb->SparingTableLoc[i], BC2
543 ));
544 continue;
545 }
546
547 BC2 = ((sizeof(SPARING_TABLE) +
548 Vcb->SparingCount*sizeof(SparingEntry) +
549 Vcb->BlockSize-1)
550 >> Vcb->BlockSizeBits);
551 if(BC2 > BC) {
552 UDFPrint((" new sizeSparingTable @%x too long: %x > %x\n",
553 Vcb->SparingTableLoc[i], BC2, BC
554 ));
555 continue;
556 }
557
558 SparTable->reallocationTableLen = (USHORT)Vcb->SparingCount;
559 RtlCopyMemory((SparTable+1), RelocMap, Vcb->SparingCount*sizeof(SparingEntry));
560/*
561 merged = FALSE;
562 NewRelocMap = (PSPARING_MAP)(SparTable+1);
563 for(n=0; n<SparTable->reallocationTableLen; n++) {
564 for(m=0; m<Vcb->SparingCount; m++) {
565 if(RelocMap[m].mappedLocation == NewRelocMap[n].mappedLocation) {
566 if(RelocMap[m].origLocation != NewRelocMap[n].origLocation) {
567 UDFPrint((" update @%x (%x) -> @%x (%x)\n",
568 NewRelocMap[m].origLocation, NewRelocMap[m].mappedLocation,
569 RelocMap[m].origLocation, RelocMap[m].mappedLocation));
570 merged = TRUE;
571 }
572 }
573 }
574 }
575*/
576// if(merged) {
577 UDFPrint(("UDF: record updated\n"));
578 status = UDFWriteSectors(Vcb, FALSE, Vcb->SparingTableLoc[i], BC2, FALSE, (int8*)SparTable, &ReadBytes);
579 if(!OS_SUCCESS(status)) {
580 if(!OS_SUCCESS(status2)) {
581 status2 = status;
582 }
583// }
584 }
585 }
586 }
587 MyFreePool__(SparTable);
588 if(!OS_SUCCESS(status2)) {
589 status = status2;
590 }
591 return status;
592} // end UDFUpdateSparingTable()
593
594/*
595 update Logical volume descriptor
596 */
599 IN PVCB Vcb,
600 IN UDF_VDS_RECORD Lba,
601 IN PUNICODE_STRING VolIdent
602 )
603{
604 LogicalVolDesc* lvd = NULL;
605#define CUR_IDENT_SZ (sizeof(lvd->logicalVolIdent))
608 SIZE_T WrittenBytes;
610// OSSTATUS status2 = STATUS_SUCCESS;
611
613
614 if(!(Vcb->CompatFlags & UDF_VCB_IC_W2K_COMPAT_VLABEL)) {
615 goto Err_SetVI;
616 }
617
618 lvd = (LogicalVolDesc*)MyAllocatePool__(NonPagedPool, max(Vcb->BlockSize, sizeof(LogicalVolDesc)) );
619
620 if(!lvd) {
622 goto Err_SetVI;
623 }
624
625 UDFPrint(("UDF: Updating LVD @%x (%x)\n", Lba.block, Vcb->BlockSize));
626
627 status = UDFSetDstring(&(Vcb->VolIdent), (dstring*)&CS0, CUR_IDENT_SZ);
628 if(!OS_SUCCESS(status)) {
631 }
632 goto Err_SetVI;
633 }
634
635 if(!Lba.block) {
637 goto Err_SetVI;
638 }
639 status = UDFReadTagged(Vcb, (int8*)lvd, Lba.block, Lba.block, &ident);
640 if(!OS_SUCCESS(status)) goto Err_SetVI;
643 goto Err_SetVI;
644 }
645
647 // no changes
648 UDFPrint(("UDF: equal VolIds\n"));
650 goto Err_SetVI;
651 }
653
654 lvd->descTag.tagSerialNum --;
655 UDFSetUpTag(Vcb, (tag*)lvd, lvd->descTag.descCRCLength, Lba.block);
656
657 status = UDFWriteSectors(Vcb, TRUE, Lba.block, 1, FALSE, (int8*)lvd, &WrittenBytes);
658
659Err_SetVI:
660 if(lvd)
661 MyFreePool__(lvd);
662
663#undef CUR_IDENT_SZ
664//#endif //0
665
666 return status;
667} // end UDFUpdateLogicalVol()
668
669/*
670 This routine updates volume descriptor sequence
671 */
674 IN PVCB Vcb,
676 IN uint32 lastblock,
678 )
679{
681 int8* Buf = (int8*)DbgAllocatePool(NonPagedPool,Vcb->LBlockSize);
683 uint32 i,j;
685
686 if (!Buf) return STATUS_INSUFFICIENT_RESOURCES;
688 if(!OS_SUCCESS(status = UDFReadVDS(Vcb, block, lastblock, (PUDF_VDS_RECORD)&vds, Buf))) {
689 DbgFreePool(Buf);
690 return status;
691 }
692
693/*
694 // update USD (if any)
695 for (i=0; i<VDS_POS_LENGTH; i++) {
696 if (vds[i].block) {
697 status = UDFReadTagged(Vcb, Buf, vds[i].block, vds[i].block, &ident);
698 if(OS_SUCCESS(status) && (i == VDS_POS_PARTITION_DESC)) {
699 // load partition descriptor(s)
700 int8* Buf2 = (int8*)DbgAllocatePool(NonPagedPool,Vcb->BlockSize);
701 if (!Buf2) {
702 DbgFreePool(Buf);
703 return STATUS_INSUFFICIENT_RESOURCES;
704 }
705 for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++) {
706 UDFReadTagged(Vcb,Buf2, j, j, &ident);
707 if (ident == TID_UNALLOC_SPACE_DESC)
708 // This implememtation doesn't support USD ;) recording
709 // So, we'll make'em blank, but record all bitmaps
710 UDFUpdateUSpaceDesc(Vcb,Buf2);
711 }
712 DbgFreePool(Buf2);
713 break;
714 }
715 }
716 }*/
717 for (i=0; i<VDS_POS_LENGTH; i++) {
718 if (vds[i].block) {
719 status = UDFReadTagged(Vcb, Buf, vds[i].block, vds[i].block, &ident);
720 if(!OS_SUCCESS(status))
721 continue;
722 // update XBMs
724 if(!(flags & 1))
725 continue;
726 // update partition descriptor(s)
727 int8* Buf2 = (int8*)DbgAllocatePool(NonPagedPool,Vcb->BlockSize);
728 if (!Buf2) {
729 DbgFreePool(Buf);
731 }
733 for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++) {
734 UDFReadTagged(Vcb,Buf2, j, j, &ident);
737 }
738 DbgFreePool(Buf2);
739// continue;
740 } else
741 // update Vol Ident Desc
744 if(!OS_SUCCESS(status))
745 continue;
746 }
747 }
748 }
749
750 DbgFreePool(Buf);
751 return status;
752} // end UDFUpdateVDS()
753#endif //UDF_READ_ONLY_BUILD
754
758 IN PUNICODE_STRING UName,
759 IN dstring* Dest,
761 )
762{
763 uint8* CS0;
764 SIZE_T len = Length-1;
765
766 UDFCompressUnicode(UName, &CS0, &len);
767 if(!CS0)
769 if(len > Length-1) {
770 MyFreePool__(CS0);
772 }
773 RtlCopyMemory(Dest, CS0, len);
774 MyFreePool__(CS0);
775 if(len < Length-1)
776 RtlZeroMemory(Dest+len, Length-1-len);
777 Dest[Length-1] = (uint8)len;
778 return TRUE;
779} // end UDFSetDstring()
780
781void
784 IN OUT PUNICODE_STRING UName,
785 IN dstring* Dest,
787 )
788{
789 uint32 len = Dest[Length-1];
790
791 UDFDecompressUnicode(UName, Dest, len, NULL);
792 return;
793} // end UDFGetDstring()
794
795#ifndef UDF_READ_ONLY_BUILD
796/*
797 This routine updates Volume Label & some other features stored in
798 VolIdentDesc
799 */
802 IN PVCB Vcb,
803 IN UDF_VDS_RECORD Lba,
804 IN PUNICODE_STRING VolIdent
805 )
806{
807#define CUR_IDENT_SZ (sizeof(pvoldesc->volIdent))
812 SIZE_T WrittenBytes;
813
814 if(!pvoldesc) return STATUS_INSUFFICIENT_RESOURCES;
815
816 UDFPrint(("UDF: Updating PVD @%x (%x)\n", Lba.block, Vcb->BlockSize));
817
818 status = UDFSetDstring(&(Vcb->VolIdent), (dstring*)&CS0, CUR_IDENT_SZ);
819 if(!OS_SUCCESS(status)) {
822 }
823 goto Err_SetVI;
824 }
825
826 if(!Lba.block) {
828 goto Err_SetVI;
829 }
830 status = UDFReadTagged(Vcb, (int8*)pvoldesc, Lba.block, Lba.block, &ident);
831 if(!OS_SUCCESS(status)) goto Err_SetVI;
834 goto Err_SetVI;
835 }
836
837 if(RtlCompareMemory(pvoldesc->volIdent, CS0, CUR_IDENT_SZ) == CUR_IDENT_SZ) {
838 // no changes
840 goto Err_SetVI;
841 }
842 RtlCopyMemory(pvoldesc->volIdent, CS0, CUR_IDENT_SZ);
843
844 pvoldesc->descTag.tagSerialNum --;
845 UDFSetUpTag(Vcb, (tag*)pvoldesc, pvoldesc->descTag.descCRCLength, Lba.block);
846
847 status = UDFWriteSectors(Vcb, TRUE, Lba.block, 1, FALSE, (int8*)pvoldesc, &WrittenBytes);
848Err_SetVI:
849 MyFreePool__(pvoldesc);
850 return status;
851
852#undef CUR_IDENT_SZ
853} // end UDFUpdateVolIdent()
854#endif //UDF_READ_ONLY_BUILD
855
858 IN PVCB Vcb
859 )
860{
861 uint32 PartNum;
862 uint32 i;
863 uint32 plen, pstart, pend;
864 int8* bad_bm;
866 PEXTENT_MAP Map = NULL;
867 PEXTENT_INFO DataLoc;
868
869 UDFPrint(("UDFUpdateNonAllocated:\n"));
870 if(!Vcb->NonAllocFileInfo) {
871 return STATUS_SUCCESS;
872 }
873 if(!(bad_bm = Vcb->BSBM_Bitmap)) {
874 return STATUS_SUCCESS;
875 }
876
877 DataLoc = &(Vcb->NonAllocFileInfo->Dloc->DataLoc);
878 ASSERT(!DataLoc->Offset);
879 if(Vcb->NonAllocFileInfo->Dloc->DataLoc.Offset) {
880 UDFPrint(("NonAllocFileInfo in IN_ICB mode !!!\n"));
881 return STATUS_SUCCESS;
882 }
883 PartNum = UDFGetPartNumByPhysLba(Vcb, Vcb->NonAllocFileInfo->Dloc->FELoc.Mapping[0].extLocation);
884 pstart = UDFPartStart(Vcb, PartNum);
885 plen = UDFPartLen(Vcb, PartNum);
886 pend = min(pstart + plen, Vcb->FSBM_BitCount);
887
888 //BrutePoint();
889 for(i=pstart; i<pend; i++) {
890 if(!UDFGetBadBit(bad_bm, i))
891 continue;
892 // add BAD blocks to unallocatable space
893 // if the block is already in NonAllocatable, ignore it
895 UDFPrint(("lba %#x is already in NonAllocFileInfo\n", i));
896 continue;
897 }
898 UDFPrint(("add lba %#x to NonAllocFileInfo\n", i));
899 DataLoc->Modified = TRUE;
900 Ext.extLength = Vcb->LBlockSize;
901 // align lba on LogicalBlock boundary
902 Ext.extLocation = i & ~((1<<Vcb->LB2B_Bits) - 1);
903 Map = UDFExtentToMapping(&Ext);
904 DataLoc->Mapping = UDFMergeMappings(DataLoc->Mapping, Map);
905 }
906 UDFPackMapping(Vcb, DataLoc);
907 DataLoc->Length = UDFGetExtentLength(DataLoc->Mapping);
908 UDFFlushFile__(Vcb, Vcb->NonAllocFileInfo);
909
910 // ensure that BAD space is marked as USED
911 UDFMarkSpaceAsXXX(Vcb, 0, &(DataLoc->Mapping[0]), AS_USED); // mark as used
912
913 UDFPrint(("UDFUpdateNonAllocated: done\n"));
914 return STATUS_SUCCESS;
915} // end UDFUpdateNonAllocated()
916
917/*
918 This routine rebuilds & flushes all system areas
919 */
922 IN PVCB Vcb
923 )
924{
925#ifndef UDF_READ_ONLY_BUILD
926 uint32 flags = 0;
927
928 if((Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)
929 || !Vcb->Modified)
930 return STATUS_SUCCESS;
931 // prevent discarding metadata
932 Vcb->VCBFlags |= UDF_VCB_ASSUME_ALL_USED;
933 if(Vcb->CDR_Mode) {
934 // flush internal cache
935 if(WCacheGetWriteBlockCount__(&(Vcb->FastCache)) >= (Vcb->WriteBlockSize >> Vcb->BlockSizeBits) )
936 WCacheFlushAll__(&(Vcb->FastCache), Vcb);
937 // record VAT
938 return UDFRecordVAT(Vcb);
939 }
940
943
944 if(Vcb->VerifyOnWrite) {
945 UDFPrint(("UDF: Flushing cache for verify\n"));
946 //WCacheFlushAll__(&(Vcb->FastCache), Vcb);
947 WCacheFlushBlocks__(&(Vcb->FastCache), Vcb, 0, Vcb->LastLBA);
948 UDFVFlush(Vcb);
949 }
950
951 // synchronize BAD Block bitmap and NonAllocatable
953
954 UDFAcquireResourceExclusive(&(Vcb->BitMapResource1),TRUE);
955
956 // RAM mode
957#ifdef UDF_DBG
958 if(!OS_SUCCESS(UDFUpdateVolIdent(Vcb, Vcb->PVolDescAddr, &(Vcb->VolIdent))))
959 UDFPrint(("Error updating VolIdent (1)\n"));
960 if(!OS_SUCCESS(UDFUpdateVolIdent(Vcb, Vcb->PVolDescAddr2, &(Vcb->VolIdent))))
961 UDFPrint(("Error updating VolIdent (2)\n"));
962#else
963 UDFUpdateVolIdent(Vcb, Vcb->PVolDescAddr, &(Vcb->VolIdent));
964 UDFUpdateVolIdent(Vcb, Vcb->PVolDescAddr2, &(Vcb->VolIdent));
965#endif // UDF_DBG
966
968 // check if we should update BM
969 if(Vcb->FSBM_ByteCount == RtlCompareMemory(Vcb->FSBM_Bitmap, Vcb->FSBM_OldBitmap, Vcb->FSBM_ByteCount)) {
970 flags &= ~1;
971 } else {
972 flags |= 1;
973 }
974
975#ifdef UDF_DBG
976 if(!OS_SUCCESS(UDFUpdateVDS(Vcb, Vcb->VDS1, Vcb->VDS1 + Vcb->VDS1_Len, flags)))
977 UDFPrint(("Error updating Main VDS\n"));
978 if(!OS_SUCCESS(UDFUpdateVDS(Vcb, Vcb->VDS2, Vcb->VDS2 + Vcb->VDS2_Len, flags)))
979 UDFPrint(("Error updating Reserve VDS\n"));
980#else
981 UDFUpdateVDS(Vcb, Vcb->VDS1, Vcb->VDS1 + Vcb->VDS1_Len, flags);
982 UDFUpdateVDS(Vcb, Vcb->VDS2, Vcb->VDS2 + Vcb->VDS2_Len, flags);
983#endif // UDF_DBG
984
985 // Update Integrity Desc if any
986 if(Vcb->LVid && Vcb->origIntegrityType == INTEGRITY_TYPE_CLOSE) {
988 }
989
990 if(flags & 1)
991 RtlCopyMemory(Vcb->FSBM_OldBitmap, Vcb->FSBM_Bitmap, Vcb->FSBM_ByteCount);
992
993//skip_update_bitmap:
994
995 Vcb->VCBFlags &= ~UDF_VCB_ASSUME_ALL_USED;
996
997 UDFReleaseResource(&(Vcb->BitMapResource1));
998#endif //UDF_READ_ONLY_BUILD
999
1000 return STATUS_SUCCESS;
1001} // end UDFUmount__()
1002
1003/*************************************************************************/
1004
1005/*
1006 Find an anchor volume descriptor.
1007 The UDFGetDiskInfoAndVerify() will invoke this routine to find & check
1008 Anchor Volume Descriptors on the target device
1009*/
1010lba_t
1012 PVCB Vcb // Volume control block
1013 )
1014{
1015// OSSTATUS RC = STATUS_SUCCESS;
1016
1017 uint16 ident;
1018 uint32 i;
1019 uint32 LastBlock;
1021 int8* Buf = (int8*)MyAllocatePool__(NonPagedPool,Vcb->BlockSize);
1022 BOOLEAN MRW_candidate;
1023 BOOLEAN IsMRW = (Vcb->MRWStatus != 0);
1024 if(!Buf)
1025 return 0;
1026
1027 UDFPrint(("UDFFindAnchor\n"));
1028 // init probable locations...
1029 RtlZeroMemory(&(Vcb->Anchor), sizeof(Vcb->Anchor));
1030 Vcb->Anchor[0] = 256 + Vcb->FirstLBALastSes;
1031 Vcb->Anchor[1] = 512 + Vcb->FirstLBALastSes;
1032 Vcb->Anchor[2] = 256 + Vcb->TrackMap[Vcb->LastTrackNum].FirstLba;
1033 Vcb->Anchor[3] = 512 + Vcb->TrackMap[Vcb->LastTrackNum].FirstLba;
1034 Vcb->Anchor[4] = Vcb->LastLBA - 256;
1035 Vcb->Anchor[5] = Vcb->LastLBA - 256 + 1;
1036 Vcb->Anchor[6] = Vcb->LastLBA - 256 - 2;
1037 // vat locations
1038 Vcb->Anchor[7] = Vcb->LastLBA - 2;
1039 Vcb->Anchor[8] = Vcb->LastLBA;
1040 Vcb->Anchor[9] = Vcb->LastLBA - 512;
1041// Vcb->Anchor[7] = Vcb->LastLBA - 256 - 7;
1042// Vcb->Anchor[8] = Vcb->LastLBA - 512 - 2;
1043// Vcb->Anchor[9] = Vcb->LastLBA - 512 - 7;
1044
1045 LastBlock = 0;
1046 // ... and check them
1047 for (i=0; i<sizeof(Vcb->Anchor)/sizeof(int); i++) {
1048 if(Vcb->Anchor[i] > Vcb->LastLBA)
1049 Vcb->Anchor[i] = 0;
1050 MRW_candidate = FALSE;
1051 if(Vcb->Anchor[i]) {
1052 UDFPrint(("check Anchor %x\n", Vcb->Anchor[i]));
1054 Vcb->Anchor[i], Vcb->Anchor[i], &ident))) {
1055
1056 // Fucking MRW...
1057 if(!IsMRW && (i<2) &&
1058 (Vcb->CompatFlags & UDF_VCB_IC_MRW_ADDR_PROBLEM)) {
1060 Vcb->Anchor[i]+MRW_DMA_OFFSET, Vcb->Anchor[i], &ident))) {
1061 // do MRW workaround.....
1062 UDFPrint(("UDF: looks like we have MRW....\n"));
1063 MRW_candidate = TRUE;
1064 goto MRW_workaround;
1065 }
1066 }
1067
1068 Vcb->Anchor[i] = 0;
1070 UDFPrint(("UDF: disk seems to be incomplete\n"));
1071 break;
1072 }
1073 } else {
1074MRW_workaround:
1075 if((ident != TID_ANCHOR_VOL_DESC_PTR) && ((i<6) ||
1077 Vcb->Anchor[i] = 0;
1078 } else {
1079 UDFPrint(("UDF: Found AVD at %x (point %d)\n",Vcb->Anchor[i], i));
1080 if(!LastBlock)
1081 LastBlock = Vcb->LastLBA;
1082 if(MRW_candidate) {
1083 UDFPrint(("UDF: looks like we _*really*_ have MRW....\n"));
1084 IsMRW = TRUE;
1085 ASSERT(Vcb->LastReadTrack == 1);
1086 Vcb->TrackMap[Vcb->LastReadTrack].Flags |= TrackMap_FixMRWAddressing;
1087 WCachePurgeAll__(&(Vcb->FastCache), Vcb);
1088 UDFPrint(("UDF: MRW on non-MRW drive => ReadOnly"));
1090
1091 UDFRegisterFsStructure(Vcb, Vcb->Anchor[i], Vcb->BlockSize);
1092
1093 }
1094 }
1095 }
1096 }
1097 }
1098
1099 UDFPrint(("UDF: -----------------\nUDF: Last block %x\n",LastBlock));
1100 MyFreePool__(Buf);
1101 return LastBlock;
1102} // end UDFFindAnchor()
1103
1104/*
1105 Look for Volume recognition sequence
1106 */
1107uint32
1109 PVCB Vcb
1110 )
1111{
1112 VolStructDesc *vsd = NULL;
1113 uint32 offset;
1114 uint32 retStat = 0;
1115 uint32 BeginOffset = Vcb->FirstLBA;
1116 OSSTATUS RC;
1119
1120 if(!buffer) return 0;
1121 // Relative to First LBA in Last Session
1122 offset = Vcb->FirstLBA + 0x10;
1123
1124 UDFPrint(("UDFFindVRS:\n"));
1125
1126 // Process the sequence (if applicable)
1127 for (;(offset-BeginOffset <=0x20); offset ++) {
1128 // Read a block
1130 if(!OS_SUCCESS(RC)) continue;
1131
1132 // Look for ISO descriptors
1133 vsd = (VolStructDesc *)(buffer);
1134
1135 if(vsd->stdIdent[0]) {
1136 if(!strncmp((int8*)(&vsd->stdIdent), STD_ID_CD001, STD_ID_LEN))
1137 {
1138 retStat |= VRS_ISO9660_FOUND;
1139 switch (vsd->structType)
1140 {
1141 case 0:
1142 UDFPrint(("UDF: ISO9660 Boot Record found\n"));
1143 break;
1144 case 1:
1145 UDFPrint(("UDF: ISO9660 Primary Volume Descriptor found\n"));
1146 break;
1147 case 2:
1148 UDFPrint(("UDF: ISO9660 Supplementary Volume Descriptor found\n"));
1149 break;
1150 case 3:
1151 UDFPrint(("UDF: ISO9660 Volume Partition Descriptor found\n"));
1152 break;
1153 case 255:
1154 UDFPrint(("UDF: ISO9660 Volume Descriptor Set Terminator found\n"));
1155 break;
1156 default:
1157 UDFPrint(("UDF: ISO9660 VRS (%u) found\n", vsd->structType));
1158 break;
1159 }
1160 }
1161 else if(!strncmp((int8*)(&vsd->stdIdent), STD_ID_BEA01, STD_ID_LEN))
1162 {
1163 UDFPrint(("UDF: BEA01 Found\n"));
1164 }
1165 else if(!strncmp((int8*)(&vsd->stdIdent), STD_ID_TEA01, STD_ID_LEN))
1166 {
1167 UDFPrint(("UDF: TEA01 Found\n"));
1168 break;
1169 }
1170 else if(!strncmp((int8*)(&vsd->stdIdent), STD_ID_NSR02, STD_ID_LEN))
1171 {
1172 retStat |= VRS_NSR02_FOUND;
1173 UDFPrint(("UDF: NSR02 Found\n"));
1174 break;
1175 }
1176 else if(!strncmp((int8*)(&vsd->stdIdent), STD_ID_NSR03, STD_ID_LEN))
1177 {
1178 retStat |= VRS_NSR03_FOUND;
1179 UDFPrint(("UDF: NSR03 Found\n"));
1180 break;
1181 }
1182 }
1183 }
1184
1186
1187 return retStat;
1188} // end UDFFindVRS()
1189
1190/*
1191 process Primary volume descriptor
1192 */
1193void
1195 PVCB Vcb,
1196 int8* Buf // pointer to buffer containing PVD
1197 )
1198{
1199 PrimaryVolDesc *pvoldesc;
1200// OSSTATUS RC = STATUS_SUCCESS;
1201
1202 pvoldesc = (PrimaryVolDesc *)Buf;
1203 UDFPrint(("UDF: PrimaryVolDesc:\n"));
1204 UDFPrint(("volDescSeqNum = %d\n", pvoldesc->volDescSeqNum));
1205 UDFPrint(("primaryVolDescNum = %d\n", pvoldesc->primaryVolDescNum));
1206 // remember recording time...
1207 Vcb->VolCreationTime = UDFTimeToNT(&(pvoldesc->recordingDateAndTime));
1208 // ...VolIdent...
1209#define CUR_IDENT_SZ (sizeof(pvoldesc->volIdent))
1210 if (Vcb->VolIdent.Buffer) {
1211 MyFreePool__(Vcb->VolIdent.Buffer);
1212 }
1213 UDFGetDstring(&(Vcb->VolIdent), (dstring*)&(pvoldesc->volIdent), CUR_IDENT_SZ);
1214#undef CUR_IDENT_SZ
1215 UDFPrint(("volIdent[] = '%ws'\n", Vcb->VolIdent.Buffer));
1216#ifdef UDF_DBG
1217 UDFPrint(("volSeqNum = %d\n", pvoldesc->volSeqNum));
1218 UDFPrint(("maxVolSeqNum = %d\n", pvoldesc->maxVolSeqNum));
1219 UDFPrint(("interchangeLvl = %d\n", pvoldesc->interchangeLvl));
1220 UDFPrint(("maxInterchangeLvl = %d\n", pvoldesc->maxInterchangeLvl));
1221 UDFPrint(("charSetList = %d\n", pvoldesc->charSetList));
1222 UDFPrint(("maxCharSetList = %d\n", pvoldesc->maxCharSetList));
1223 // ...& just print VolSetIdent
1224 UNICODE_STRING instr;
1225#define CUR_IDENT_SZ (sizeof(pvoldesc->volSetIdent))
1226 UDFGetDstring(&instr, (dstring*)&(pvoldesc->volSetIdent), CUR_IDENT_SZ);
1227#undef CUR_IDENT_SZ
1228 UDFPrint(("volSetIdent[] = '%ws'\n", instr.Buffer));
1229// UDFPrint(("maxInterchangeLvl = %d\n", pvoldesc->maxInterchangeLvl));
1230 UDFPrint(("flags = %x\n", pvoldesc->flags));
1231 if(instr.Buffer) MyFreePool__(instr.Buffer);
1232#endif // UDF_DBG
1233} // end UDFLoadPVolDesc()
1234
1235/*
1236 load Logical volume integrity descriptor
1237 */
1241 PVCB Vcb,
1242 extent_ad loc
1243 )
1244{
1246 uint32 len;
1247 SIZE_T _ReadBytes;
1248 int8* Buf = NULL;
1249 uint16 ident;
1251 LogicalVolHeaderDesc* LVID_hd;
1252 extent_ad last_loc;
1253 BOOLEAN read_last = FALSE;
1254 uint32 lvid_count = 0;
1255
1256 ASSERT(!Vcb->LVid);
1257 if(Vcb->LVid) {
1258 MyFreePool__(Vcb->LVid);
1259 Vcb->LVid = NULL;
1260 }
1261 // walk through all sectors inside LogicalVolumeIntegrityDesc
1262 while(loc.extLength) {
1263 UDFPrint(("UDF: Reading LVID @%x (%x)\n", loc.extLocation, loc.extLength));
1264 len = max(loc.extLength, Vcb->BlockSize);
1266 if(!Buf)
1268 RC = UDFReadTagged(Vcb,Buf, loc.extLocation, loc.extLocation, &ident);
1269 if(!OS_SUCCESS(RC)) {
1270exit_with_err:
1271 UDFPrint(("UDF: Reading LVID @%x (%x) failed.\n", loc.extLocation, loc.extLength));
1272 switch(Vcb->PartitialDamagedVolumeAction) {
1274 UDFPrint(("UDF: Switch to r/o mode.\n"));
1276 Vcb->UserFSFlags |= UDF_USER_FS_FLAGS_MEDIA_DEFECT_RO;
1277 RC = STATUS_SUCCESS;
1278 break;
1280 UDFPrint(("UDF: Switch to raw mount mode, return UNRECOGNIZED_VOLUME.\n"));
1281 Vcb->VCBFlags |= UDF_VCB_FLAGS_RAW_DISK;
1282 //RC = STATUS_WRONG_VOLUME;
1283 break;
1285 default:
1286 UDFPrint(("UDF: Keep r/w mode for your own risk.\n"));
1287 RC = STATUS_SUCCESS;
1288 // asume we have INTEGRITY_TYPE_CLOSE
1289 Vcb->IntegrityType = INTEGRITY_TYPE_CLOSE;
1290 break;
1291 }
1292
1293 MyFreePool__(Buf);
1294 return RC;
1295 }
1297 // handle Terminal Entry
1298 if(ident == TID_TERMINAL_ENTRY) {
1299 read_last = TRUE;
1300 MyFreePool__(Buf);
1301 Vcb->LVid = NULL;
1302 loc = last_loc;
1303 continue;
1304 } else
1307 goto exit_with_err;
1308 }
1309
1310 Vcb->LVid = (LogicalVolIntegrityDesc *)Buf;
1311 RC = UDFReadData(Vcb, TRUE, ((uint64)(loc.extLocation)) << Vcb->BlockSizeBits, len, FALSE, Buf, &_ReadBytes);
1312 // update info
1313 if( !read_last &&
1314 Vcb->LVid->nextIntegrityExt.extLength) {
1315 // go to next LVID
1316 last_loc = loc;
1317 loc = Vcb->LVid->nextIntegrityExt;
1318 Vcb->LVid = NULL;
1319 lvid_count++;
1320 if(lvid_count > UDF_MAX_LVID_CHAIN_LENGTH) {
1322 goto exit_with_err;
1323 }
1324 MyFreePool__(Buf);
1325 continue;
1326 }
1327 // process last LVID
1328 Vcb->origIntegrityType =
1329 Vcb->IntegrityType = Vcb->LVid->integrityType;
1330 Vcb->LVid_loc = loc;
1331
1332 LVID_iUse = UDFGetLVIDiUse(Vcb);
1333
1334 UDFPrint(("UDF: Last LVID:\n"));
1335 UDFPrint((" minR: %x\n",LVID_iUse->minUDFReadRev ));
1336 UDFPrint((" minW: %x\n",LVID_iUse->minUDFWriteRev));
1337 UDFPrint((" maxW: %x\n",LVID_iUse->maxUDFWriteRev));
1338 UDFPrint((" Type: %s\n",!Vcb->IntegrityType ? "Open" : "Close"));
1339
1340 Vcb->minUDFReadRev = LVID_iUse->minUDFReadRev;
1341 Vcb->minUDFWriteRev = LVID_iUse->minUDFWriteRev;
1342 Vcb->maxUDFWriteRev = LVID_iUse->maxUDFWriteRev;
1343
1344 Vcb->numFiles = LVID_iUse->numFiles;
1345 Vcb->numDirs = LVID_iUse->numDirs;
1346 UDFPrint((" nFiles: %x\n",Vcb->numFiles ));
1347 UDFPrint((" nDirs: %x\n",Vcb->numDirs ));
1348
1349 // Check if we can understand this format
1350 if(Vcb->minUDFReadRev > UDF_MAX_READ_REVISION)
1352 // Check if we know how to write here
1353 if(Vcb->minUDFWriteRev > UDF_MAX_WRITE_REVISION) {
1354 UDFPrint((" Target FS requires: %x Revision => ReadOnly\n",Vcb->minUDFWriteRev));
1356 Vcb->UserFSFlags |= UDF_USER_FS_FLAGS_NEW_FS_RO;
1357 }
1358
1359 LVID_hd = (LogicalVolHeaderDesc*)&(Vcb->LVid->logicalVolContentsUse);
1360 Vcb->NextUniqueId = LVID_hd->uniqueID;
1361 UDFPrint((" Next FID: %x\n",Vcb->NextUniqueId));
1362
1363 break;
1364 }
1365
1366 return RC;
1367} // end UDFLoadLogicalVolInt()
1368
1369
1370/*
1371 load Logical volume descriptor
1372 */
1376 PVCB Vcb,
1377 int8* Buf,
1378 lb_addr *fileset
1379 )
1380{
1381 LogicalVolDesc *lvd = (LogicalVolDesc *)Buf;
1382 uint16 i, offset;
1383 uint8 type;
1385 UDFPrint(("UDF: LogicalVolDesc\n"));
1386 // Validate partition map counter
1387 if(!(Vcb->Partitions)) {
1388 Vcb->PartitionMaps = lvd->numPartitionMaps;
1389 Vcb->Partitions = (PUDFPartMap)MyAllocatePool__(NonPagedPool, sizeof(UDFPartMap) * Vcb->PartitionMaps );
1390 if(!Vcb->Partitions)
1392 } else {
1393 if(Vcb->PartitionMaps != lvd->numPartitionMaps)
1395 }
1396 UDFPrint(("UDF: volDescSeqNum = %x\n", lvd->volDescSeqNum));
1397 // Get logical block size (may be different from physical)
1398 Vcb->LBlockSize = lvd->logicalBlockSize;
1399 // Get current UDF revision
1400 // Get Read-Only flags
1402
1403 if(Vcb->LBlockSize < Vcb->BlockSize)
1405 switch(Vcb->LBlockSize) {
1406 case 512: Vcb->LBlockSizeBits = 9; break;
1407 case 1024: Vcb->LBlockSizeBits = 10; break;
1408 case 2048: Vcb->LBlockSizeBits = 11; break;
1409 case 4096: Vcb->LBlockSizeBits = 12; break;
1410 case 8192: Vcb->LBlockSizeBits = 13; break;
1411 case 16384: Vcb->LBlockSizeBits = 14; break;
1412 case 32768: Vcb->LBlockSizeBits = 15; break;
1413 case 65536: Vcb->LBlockSizeBits = 16; break;
1414 default:
1415 UDFPrint(("UDF: Bad block size (%ld)\n", Vcb->LBlockSize));
1417 }
1418 UDFPrint(("UDF: logical block size (%ld)\n", Vcb->LBlockSize));
1419 Vcb->LB2B_Bits = Vcb->LBlockSizeBits - Vcb->BlockSizeBits;
1420 UDFPrint(("UDF: mapTableLength = %x\n", lvd->mapTableLength));
1421 UDFPrint(("UDF: numPartitionMaps = %x\n", lvd->numPartitionMaps));
1422 // walk through all available part maps
1423 for (i=0,offset=0;
1424 i<Vcb->PartitionMaps && offset<lvd->mapTableLength;
1425 i++,offset+=((GenericPartitionMap *)( ((uint8*)(lvd+1))+offset) )->partitionMapLength)
1426 {
1427 GenericPartitionMap* gpm = (GenericPartitionMap *)(((uint8*)(lvd+1))+offset);
1428 type = gpm->partitionMapType;
1429 UDFPrint(("Partition (%d) type %x, len %x\n", i, type, gpm->partitionMapLength));
1431 {
1432 GenericPartitionMap1 *gpm1 = (GenericPartitionMap1 *)(((uint8*)(lvd+1))+offset);
1433
1434 Vcb->Partitions[i].PartitionType = UDF_TYPE1_MAP15;
1435 Vcb->Partitions[i].VolumeSeqNum = gpm1->volSeqNum;
1436 Vcb->Partitions[i].PartitionNum = gpm1->partitionNum;
1438 }
1439 else if(type == PARTITION_MAP_TYPE_2)
1440 {
1441 UdfPartitionMap2* upm2 = (UdfPartitionMap2 *)(((uint8*)(lvd+1))+offset);
1443 {
1444 UDFIdentSuffix* udfis =
1446
1447 if( (udfis->currentRev == 0x0150)/* ||
1448 (Vcb->CurrentUDFRev == 0x0150)*/ ) {
1449 UDFPrint(("Found VAT 1.50\n"));
1450 Vcb->Partitions[i].PartitionType = UDF_VIRTUAL_MAP15;
1451 } else
1452 if( (udfis->currentRev == 0x0200) ||
1453 (udfis->currentRev == 0x0201) /*||
1454 (Vcb->CurrentUDFRev == 0x0200) ||
1455 (Vcb->CurrentUDFRev == 0x0201)*/ ) {
1456 UDFPrint(("Found VAT 2.00\n"));
1457 Vcb->Partitions[i].PartitionType = UDF_VIRTUAL_MAP20;
1458 }
1460 }
1462 {
1463 UDFPrint(("Load sparing table\n"));
1465 Vcb->Partitions[i].PartitionType = UDF_SPARABLE_MAP15;
1467 }
1469 {
1470 UDFPrint(("Found metadata partition\n"));
1471// PMETADATA_PARTITION_MAP mpm = (PMETADATA_PARTITION_MAP)(((uint8*)(lvd+1))+offset);
1472 Vcb->Partitions[i].PartitionType = UDF_METADATA_MAP25;
1473 //status = UDFLoadSparingTable(Vcb, spm);
1474 }
1475 else
1476 {
1477 UDFPrint(("Unknown ident: %s\n", upm2->partIdent.ident));
1478 continue;
1479 }
1480 Vcb->Partitions[i].VolumeSeqNum = upm2->volSeqNum;
1481 Vcb->Partitions[i].PartitionNum = upm2->partitionNum;
1482 }
1483 }
1484
1485 if(fileset) {
1486 // remember FileSet location
1487 long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
1488 *fileset = (la->extLocation);
1489 UDFPrint(("FileSet found in LogicalVolDesc at block=%x, partition=%d\n",
1490 fileset->logicalBlockNum,
1491 fileset->partitionReferenceNum));
1492 }
1493 if(OS_SUCCESS(status)) {
1494 // load Integrity Desc if any
1495 if(lvd->integritySeqExt.extLength)
1497 }
1498 return status;
1499} // end UDFLoadLogicalVol()
1500
1504 PVCB Vcb,
1505 int8* Buf,
1506 lb_addr *fileset
1507 )
1508{
1509// LogicalVolDesc *lvd = (LogicalVolDesc *)Buf;
1510 UDFPrint(("UDF: Bogus LogicalVolDesc\n"));
1511 // Validate partition map counter
1512 if(!(Vcb->Partitions)) {
1513 Vcb->PartitionMaps = 1;
1514 Vcb->Partitions = (PUDFPartMap)MyAllocatePool__(NonPagedPool, sizeof(UDFPartMap) * Vcb->PartitionMaps );
1515 if(!Vcb->Partitions)
1517 } else {
1518 if(Vcb->PartitionMaps != 1)
1520 }
1521 UDFPrint(("UDF: volDescSeqNum = %x\n", 0));
1522 // Get logical block size (may be different from physical)
1523 Vcb->LBlockSize = 2048;
1524 // Get current UDF revision
1525 // Get Read-Only flags
1526// UDFReadEntityID_Domain(Vcb, &(lvd->domainIdent));
1527
1528 if(Vcb->LBlockSize < Vcb->BlockSize)
1530 Vcb->LBlockSizeBits = 11;
1531 UDFPrint(("UDF: logical block size (%ld)\n", Vcb->LBlockSize));
1532 Vcb->LB2B_Bits = Vcb->LBlockSizeBits - Vcb->BlockSizeBits;
1533 UDFPrint(("UDF: mapTableLength = %x\n", 0));
1534 UDFPrint(("UDF: numPartitionMaps = %x\n", 0));
1535
1536// if(CDRW) {
1537
1538 Vcb->Partitions[0].PartitionType = UDF_TYPE1_MAP15;
1539 Vcb->Partitions[0].VolumeSeqNum = 0;
1540 Vcb->Partitions[0].PartitionNum = 0;
1541
1542/* } else if(CDR)
1543 if()
1544 UDFPrint(("Found VAT 1.50\n"));
1545 Vcb->Partitions[i].PartitionType = UDF_VIRTUAL_MAP15;
1546 } else
1547 UDFPrint(("Found VAT 2.00\n"));
1548 Vcb->Partitions[i].PartitionType = UDF_VIRTUAL_MAP20;
1549 }
1550 }
1551 }
1552*/
1553 if(fileset) {
1554 // remember FileSet location
1555// long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
1556 fileset->logicalBlockNum = 0;
1557 fileset->partitionReferenceNum = 0;
1558 UDFPrint(("FileSet found in LogicalVolDesc at block=%x, partition=%d\n",
1559 fileset->logicalBlockNum,
1560 fileset->partitionReferenceNum));
1561 }
1562 return STATUS_SUCCESS;
1563} // end UDFLoadBogusLogicalVol()
1564
1565/*
1566 This routine adds given Bitmap to existing one
1567 */
1570 IN PVCB Vcb,
1571 IN uint32 PartNum,
1572 IN PSHORT_AD bm,
1573 IN ULONG bm_type
1574 )
1575{
1576 int8* tmp;
1577 int8* tmp_bm;
1578 uint32 i, lim, j, lba, l, lim2, l2, k;
1579 lb_addr locAddr;
1581 uint16 Ident;
1582 uint32 flags;
1583 SIZE_T Length;
1585 BOOLEAN bit_set;
1586
1588 UDFPrint(("UDFAddXSpaceBitmap: at block=%x, partition=%d\n",
1589 bm->extPosition,
1590 PartNum));
1591
1592 if(!(Length = (bm->extLength & UDF_EXTENT_LENGTH_MASK))) return STATUS_SUCCESS;
1593 i=UDFPartStart(Vcb, PartNum);
1594 flags = bm->extLength >> 30;
1595 if(!flags /*|| flags == EXTENT_NOT_RECORDED_ALLOCATED*/) {
1596 tmp = (int8*)DbgAllocatePool(NonPagedPool, max(Length, Vcb->BlockSize));
1597 if(!tmp) return STATUS_INSUFFICIENT_RESOURCES;
1598 locAddr.partitionReferenceNum = (uint16)PartNum;
1599 locAddr.logicalBlockNum = bm->extPosition;
1600 // read header of the Bitmap
1601 if(!OS_SUCCESS(status = UDFReadTagged(Vcb, tmp, lba = UDFPartLbaToPhys(Vcb, &(locAddr)),
1602 locAddr.logicalBlockNum, &Ident)) ) {
1603err_addxsbm_1:
1604 DbgFreePool(tmp);
1605 return status;
1606 }
1607 if(Ident != TID_SPACE_BITMAP_DESC) {
1609 goto err_addxsbm_1;
1610 }
1611 UDFRegisterFsStructure(Vcb, lba, Vcb->BlockSize);
1612 // read the whole Bitmap
1613 if(!OS_SUCCESS(status = UDFReadData(Vcb, FALSE, ((uint64)lba)<<Vcb->BlockSizeBits, Length, FALSE, tmp, &ReadBytes)))
1614 goto err_addxsbm_1;
1616 lim = min(i + ((lim2 = ((PSPACE_BITMAP_DESC)tmp)->numOfBits) << Vcb->LB2B_Bits), Vcb->FSBM_BitCount);
1617 tmp_bm = tmp + sizeof(SPACE_BITMAP_DESC);
1618 j = 0;
1619 for(;(l = UDFGetBitmapLen((uint32*)tmp_bm, j, lim2)) && (i<lim);) {
1620 // expand LBlocks to Sectors...
1621 l2 = l << Vcb->LB2B_Bits;
1622 // ...and mark them
1623 if(bm_type == UDF_FSPACE_BM) {
1624 bit_set = UDFGetFreeBit(tmp_bm, j);
1625 for(k=0;(k<l2) && (i<lim);k++) {
1626 if(bit_set) {
1627 // FREE block
1628 UDFSetFreeBit(Vcb->FSBM_Bitmap, i);
1630 UDFSetZeroBit(Vcb->ZSBM_Bitmap, i);
1631 } else {
1632 // USED block
1633 UDFClrZeroBit(Vcb->ZSBM_Bitmap, i);
1634 }
1635 i++;
1636 }
1637 } else {
1638 bit_set = UDFGetZeroBit(tmp_bm, j);
1639 for(k=0;(k<l2) && (i<lim);k++) {
1640 if(bit_set) {
1641 // ZERO block
1642 UDFSetZeroBit(Vcb->ZSBM_Bitmap, i);
1643 } else {
1644 // DATA block
1645 UDFClrZeroBit(Vcb->ZSBM_Bitmap, i);
1646 }
1647 i++;
1648 }
1649 }
1650 j += l;
1651 }
1652 DbgFreePool(tmp);
1653/* } else if((bm->extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED) {
1654 i=Vcb->Partitions[PartNum].PartitionRoot;
1655 lim = i + Vcb->Partitions[PartNum].PartitionLen;
1656 for(;i<lim;i++) {
1657 UDFSetUsedBit(Vcb->FSBM_Bitmap, i);
1658 }*/
1659 }
1660 return STATUS_SUCCESS;
1661} // end UDFAddXSpaceBitmap()
1662
1663/*
1664 This routine adds given Bitmap to existing one
1665 */
1668 IN PVCB Vcb,
1669 IN uint32 PartNum,
1670 IN PSHORT_AD bm,
1671 IN ULONG bm_type
1672 )
1673{
1674 int8* tmp;
1675// int8* tmp_bm;
1676// uint32 i, l2, k, lim, j, lim2;
1677 uint32 lba;
1678 lb_addr locAddr;
1680 uint16 Ident;
1681 uint32 flags;
1682 uint32 Length;
1684// BOOLEAN bit_set;
1685
1687
1688 UDFPrint((" UDFVerifyXSpaceBitmap: part %x\n", PartNum));
1689
1690 if(!(Length = (bm->extLength & UDF_EXTENT_LENGTH_MASK))) return STATUS_SUCCESS;
1691// i=UDFPartStart(Vcb, PartNum);
1692 flags = bm->extLength >> 30;
1693 if(!flags /*|| flags == EXTENT_NOT_RECORDED_ALLOCATED*/) {
1694 tmp = (int8*)DbgAllocatePool(NonPagedPool, max(Length, Vcb->BlockSize));
1695 if(!tmp) return STATUS_INSUFFICIENT_RESOURCES;
1696 locAddr.partitionReferenceNum = (uint16)PartNum;
1697 locAddr.logicalBlockNum = bm->extPosition;
1698 // read header of the Bitmap
1699 if(!OS_SUCCESS(status = UDFReadTagged(Vcb, tmp, lba = UDFPartLbaToPhys(Vcb, &(locAddr)),
1700 locAddr.logicalBlockNum, &Ident)) ) {
1701err_vfyxsbm_1:
1702 DbgFreePool(tmp);
1703 return status;
1704 }
1705 UDFPrint((" BM Lba %x\n", lba));
1706 if(Ident != TID_SPACE_BITMAP_DESC) {
1708 goto err_vfyxsbm_1;
1709 }
1710 // read the whole Bitmap
1711 if(!OS_SUCCESS(status = UDFReadData(Vcb, FALSE, ((uint64)lba)<<Vcb->BlockSizeBits, Length, FALSE, tmp, &ReadBytes)))
1712 goto err_vfyxsbm_1;
1714// lim = min(i + ((lim2 = ((PSPACE_BITMAP_DESC)tmp)->numOfBits) << Vcb->LB2B_Bits), Vcb->FSBM_BitCount);
1715// tmp_bm = tmp + sizeof(SPACE_BITMAP_DESC);
1716// j = 0;
1717/* for(;(l = UDFGetBitmapLen((uint32*)tmp_bm, j, lim2)) && (i<lim);) {
1718 // expand LBlocks to Sectors...
1719 l2 = l << Vcb->LB2B_Bits;
1720 // ...and mark them
1721 if(bm_type == UDF_FSPACE_BM) {
1722 bit_set = UDFGetFreeBit(tmp_bm, j);
1723 for(k=0;(k<l2) && (i<lim);k++) {
1724 if(bit_set) {
1725 // FREE block
1726 UDFSetFreeBit(Vcb->FSBM_Bitmap, i);
1727 UDFSetFreeBitOwner(Vcb, i);
1728 UDFSetZeroBit(Vcb->ZSBM_Bitmap, i);
1729 } else {
1730 // USED block
1731 UDFClrZeroBit(Vcb->ZSBM_Bitmap, i);
1732 }
1733 i++;
1734 }
1735 } else {
1736 bit_set = UDFGetZeroBit(tmp_bm, j);
1737 for(k=0;(k<l2) && (i<lim);k++) {
1738 if(bit_set) {
1739 // ZERO block
1740 UDFSetZeroBit(Vcb->ZSBM_Bitmap, i);
1741 } else {
1742 // DATA block
1743 UDFClrZeroBit(Vcb->ZSBM_Bitmap, i);
1744 }
1745 i++;
1746 }
1747 }
1748 j += l;
1749 }*/
1750 DbgFreePool(tmp);
1751/* } else if((bm->extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED) {
1752 i=Vcb->Partitions[PartNum].PartitionRoot;
1753 lim = i + Vcb->Partitions[PartNum].PartitionLen;
1754 for(;i<lim;i++) {
1755 UDFSetUsedBit(Vcb->FSBM_Bitmap, i);
1756 }*/
1757 }
1758 return STATUS_SUCCESS;
1759} // end UDFVerifyXSpaceBitmap()
1760
1761/*
1762 This routine subtracts given Bitmap to existing one
1763 */
1764/*OSSTATUS
1765UDFDelXSpaceBitmap(
1766 IN PVCB Vcb,
1767 IN uint32 PartNum,
1768 IN PSHORT_AD bm
1769 )
1770{
1771 int8* tmp, tmp_bm;
1772 uint32 i, lim, j;
1773 lb_addr locAddr;
1774 OSSTATUS status;
1775 uint16 Ident;
1776 uint32 flags;
1777 uint32 Length;
1778 SIZE_T ReadBytes;
1779
1780 if(!(Length = (bm->extLength & UDF_EXTENT_LENGTH_MASK))) return STATUS_SUCCESS;
1781 i=0;
1782 flags = bm->extLength >> 30;
1783 if(!flags || flags == EXTENT_NOT_RECORDED_ALLOCATED) {
1784 tmp = (int8*)MyAllocatePool__(NonPagedPool, Length);
1785 if(!tmp) return STATUS_INSUFFICIENT_RESOURCES;
1786 locAddr.partitionReferenceNum = (uint16)PartNum;
1787 locAddr.logicalBlockNum = bm->extPosition;
1788 if((!OS_SUCCESS(status = UDFReadTagged(Vcb, tmp, (j = UDFPartLbaToPhys(Vcb, &(locAddr))),
1789 locAddr.logicalBlockNum, &Ident))) ||
1790 (Ident != TID_SPACE_BITMAP_DESC) ) {
1791 MyFreePool__(tmp);
1792 return status;
1793 }
1794 if(!OS_SUCCESS(status = UDFReadData(Vcb, FALSE, ((uint64)j)<<Vcb->BlockSizeBits, Length, FALSE, tmp, &ReadBytes))) {
1795 MyFreePool__(tmp);
1796 return status;
1797 }
1798 lim = i + ((PSPACE_BITMAP_DESC)tmp)->numOfBits;
1799 tmp_bm = tmp + sizeof(SPACE_BITMAP_DESC);
1800 j = 0;
1801 for(;i<lim;i++) {
1802 if(UDFGetUsedBit(tmp_bm, j)) UDFSetFreeBit(Vcb->FSBM_Bitmap, i);
1803 j++;
1804 }
1805 MyFreePool__(tmp);
1806// } else if((bm->extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED) {
1807// i=Vcb->Partitions[PartNum].PartitionRoot;
1808// lim = i + Vcb->Partitions[PartNum].PartitionLen;
1809// for(;i<lim;i++) {
1810// UDFSetUsedBit(Vcb->FSBM_Bitmap, i);
1811// }
1812 }
1813 return STATUS_SUCCESS;
1814} // end UDFDelXSpaceBitmap() */
1815
1816/*
1817 This routine verifues FreeSpaceBitmap (internal) according to media
1818 parameters & input data
1819 */
1822 IN PVCB Vcb,
1823 IN uint32 PartNdx,
1824 IN PPARTITION_HEADER_DESC phd, // partition header pointing to Bitmaps
1825 IN uint32 Lba // UnallocSpaceDesc
1826 )
1827{
1829 uint32 i, l;
1830 uint16 Ident;
1831 int8* AllocDesc;
1833 lb_addr locAddr;
1834 uint32 PartNum;
1835
1836 PartNum = UDFGetPartNumByPartNdx(Vcb, PartNdx);
1837
1838 UDFPrint(("UDFVerifyFreeSpaceBitmap:\n"));
1839 // read info for partition header (if any)
1840 if(phd) {
1841 // read unallocated Bitmap
1842 if(!OS_SUCCESS(status = UDFVerifyXSpaceBitmap(Vcb, PartNum, &(phd->unallocatedSpaceBitmap), UDF_FSPACE_BM)))
1843 return status;
1844 // read freed Bitmap
1845 if(!OS_SUCCESS(status = UDFVerifyXSpaceBitmap(Vcb, PartNum, &(phd->freedSpaceBitmap), UDF_ZSPACE_BM)))
1846 return status;
1847 }
1848 // read UnallocatedSpaceDesc & convert to Bitmap
1849 if(Lba) {
1850 UDFPrint((" Lba @%x\n", Lba));
1851 if(!(AllocDesc = (int8*)MyAllocatePool__(NonPagedPool, Vcb->LBlockSize + sizeof(EXTENT_AD) )))
1853 RtlZeroMemory(((int8*)AllocDesc) + Vcb->LBlockSize, sizeof(EXTENT_AD));
1854 if(!OS_SUCCESS(status = UDFReadTagged(Vcb, AllocDesc, Lba, Lba, &Ident)) ||
1855 !(Extent = (PEXTENT_MAP)MyAllocatePool__(NonPagedPool, l = (((PUNALLOC_SPACE_DESC)AllocDesc)->numAllocDescs+1) * sizeof(EXTENT_AD) ))) {
1856 MyFreePool__(AllocDesc);
1857 return status;
1858 }
1859 UDFRegisterFsStructure(Vcb, Lba, Vcb->BlockSize);
1860 RtlCopyMemory((int8*)Extent, AllocDesc+sizeof(UNALLOC_SPACE_DESC), (((PUNALLOC_SPACE_DESC)AllocDesc)->numAllocDescs+1) * sizeof(EXTENT_AD) );
1861 locAddr.partitionReferenceNum = (uint16)PartNum;
1862 // read extent is recorded with relative addresses
1863 // so, we should convert it to suitable form
1864 for(i=0; Extent[i].extLength; i++) {
1865 locAddr.logicalBlockNum = Extent[i].extLocation;
1866 Extent[i].extLocation = UDFPartLbaToPhys(Vcb, &locAddr);
1867 if(Extent[i].extLocation == LBA_OUT_OF_EXTENT) {
1868 BrutePoint();
1869 MyFreePool__(AllocDesc);
1871 }
1872 if((Extent[i].extLocation >> 30) == EXTENT_NEXT_EXTENT_ALLOCDESC) {
1873 // load continuation
1874 Lba = Extent[i].extLocation & UDF_EXTENT_LENGTH_MASK;
1875 if(!OS_SUCCESS(status = UDFReadTagged(Vcb, AllocDesc, Lba, Lba, &Ident)) ||
1876 !(Extent = (PEXTENT_MAP)MyAllocatePool__(NonPagedPool, (((PUNALLOC_SPACE_DESC)AllocDesc)->numAllocDescs+1) * sizeof(EXTENT_AD) ))) {
1877 MyFreePool__(AllocDesc);
1878 return status;
1879 }
1880 if(Ident == TID_UNALLOC_SPACE_DESC) {
1881 UDFRegisterFsStructure(Vcb, Lba, Vcb->BlockSize);
1882 if(!(l = MyReallocPool__((int8*)Extent, l, (int8**)&Extent, i*sizeof(EXTENT_MAP)))) {
1884 MyFreePool__(AllocDesc);
1886 }
1887 Extent[i].extLength =
1888 Extent[i].extLocation = 0;
1890#ifdef UDF_DBG
1891 } else {
1892 UDFPrint(("Broken unallocated space descriptor sequence\n"));
1893#endif // UDF_DBG
1894 }
1895 }
1896 }
1897// UDFMarkSpaceAsXXX(Vcb, (-1), Extent, AS_USED); // mark as used
1899 MyFreePool__(AllocDesc);
1901 }
1902 return status;
1903} // end UDFBuildFreeSpaceBitmap()
1904
1905/*
1906 This routine builds FreeSpaceBitmap (internal) according to media
1907 parameters & input data
1908 */
1911 IN PVCB Vcb,
1912 IN uint32 PartNdx,
1913 IN PPARTITION_HEADER_DESC phd, // partition header pointing to Bitmaps
1914 IN uint32 Lba // UnallocSpaceDesc
1915 )
1916{
1918 uint32 i, l;
1919 uint16 Ident;
1920 int8* AllocDesc;
1922 lb_addr locAddr;
1923 uint32 PartNum;
1924
1925 PartNum = UDFGetPartNumByPartNdx(Vcb, PartNdx);
1926 if(!(Vcb->FSBM_Bitmap)) {
1927 // init Bitmap buffer if necessary
1928 Vcb->FSBM_Bitmap = (int8*)DbgAllocatePool(NonPagedPool, (i = (Vcb->LastPossibleLBA+1+7)>>3) );
1929 if(!(Vcb->FSBM_Bitmap)) return STATUS_INSUFFICIENT_RESOURCES;
1930
1931 Vcb->ZSBM_Bitmap = (int8*)DbgAllocatePool(NonPagedPool, (i = (Vcb->LastPossibleLBA+1+7)>>3) );
1932 if(!(Vcb->ZSBM_Bitmap)) {
1933#ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS
1934free_fsbm:
1935#endif //UDF_TRACK_ONDISK_ALLOCATION_OWNERS
1936 MyFreePool__(Vcb->FSBM_Bitmap);
1937 Vcb->FSBM_Bitmap = NULL;
1939 }
1940
1941 RtlZeroMemory(Vcb->FSBM_Bitmap, i);
1942 RtlZeroMemory(Vcb->ZSBM_Bitmap, i);
1943#ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS
1944 Vcb->FSBM_Bitmap_owners = (uint32*)DbgAllocatePool(NonPagedPool, (Vcb->LastPossibleLBA+1)*sizeof(uint32));
1945 if(!(Vcb->FSBM_Bitmap_owners)) {
1946 MyFreePool__(Vcb->ZSBM_Bitmap);
1947 Vcb->ZSBM_Bitmap = NULL;
1948 goto free_fsbm;
1949 }
1950 RtlFillMemory(Vcb->FSBM_Bitmap_owners, (Vcb->LastPossibleLBA+1)*sizeof(uint32), 0xff);
1951#endif //UDF_TRACK_ONDISK_ALLOCATION_OWNERS
1952 Vcb->FSBM_ByteCount = i;
1953 Vcb->FSBM_BitCount = Vcb->LastPossibleLBA+1;
1954 }
1955 // read info for partition header (if any)
1956 if(phd) {
1957 // read unallocated Bitmap
1958 if(!OS_SUCCESS(status = UDFAddXSpaceBitmap(Vcb, PartNum, &(phd->unallocatedSpaceBitmap), UDF_FSPACE_BM)))
1959 return status;
1960 // read freed Bitmap
1961 if(!OS_SUCCESS(status = UDFAddXSpaceBitmap(Vcb, PartNum, &(phd->freedSpaceBitmap), UDF_ZSPACE_BM)))
1962 return status;
1963 }
1964 // read UnallocatedSpaceDesc & convert to Bitmap
1965 if(Lba) {
1966 if(!(AllocDesc = (int8*)MyAllocatePool__(NonPagedPool, Vcb->LBlockSize + sizeof(EXTENT_AD) )))
1968 RtlZeroMemory(((int8*)AllocDesc) + Vcb->LBlockSize, sizeof(EXTENT_AD));
1969 if(!OS_SUCCESS(status = UDFReadTagged(Vcb, AllocDesc, Lba, Lba, &Ident)) ||
1970 !(Extent = (PEXTENT_MAP)MyAllocatePool__(NonPagedPool, l = (((PUNALLOC_SPACE_DESC)AllocDesc)->numAllocDescs+1) * sizeof(EXTENT_AD) ))) {
1971 MyFreePool__(AllocDesc);
1972 return status;
1973 }
1974 UDFRegisterFsStructure(Vcb, Lba, Vcb->BlockSize);
1975 RtlCopyMemory((int8*)Extent, AllocDesc+sizeof(UNALLOC_SPACE_DESC), (((PUNALLOC_SPACE_DESC)AllocDesc)->numAllocDescs+1) * sizeof(EXTENT_AD) );
1976 locAddr.partitionReferenceNum = (uint16)PartNum;
1977 // read extent is recorded with relative addresses
1978 // so, we should convert it to suitable form
1979 for(i=0; Extent[i].extLength; i++) {
1980 locAddr.logicalBlockNum = Extent[i].extLocation;
1981 Extent[i].extLocation = UDFPartLbaToPhys(Vcb, &locAddr);
1982 if(Extent[i].extLocation == LBA_OUT_OF_EXTENT) {
1983 BrutePoint();
1984 MyFreePool__(AllocDesc);
1986 }
1987 if((Extent[i].extLocation >> 30) == EXTENT_NEXT_EXTENT_ALLOCDESC) {
1988 // load continuation
1989 Lba = Extent[i].extLocation & UDF_EXTENT_LENGTH_MASK;
1990 if(!OS_SUCCESS(status = UDFReadTagged(Vcb, AllocDesc, Lba, Lba, &Ident)) ||
1991 !(Extent = (PEXTENT_MAP)MyAllocatePool__(NonPagedPool, (((PUNALLOC_SPACE_DESC)AllocDesc)->numAllocDescs+1) * sizeof(EXTENT_AD) ))) {
1992 MyFreePool__(AllocDesc);
1993 return status;
1994 }
1995 if(Ident == TID_UNALLOC_SPACE_DESC) {
1996 UDFRegisterFsStructure(Vcb, Lba, Vcb->BlockSize);
1997 if(!(l = MyReallocPool__((int8*)Extent, l, (int8**)&Extent, i*sizeof(EXTENT_MAP)))) {
1999 MyFreePool__(AllocDesc);
2001 }
2002 Extent[i].extLength =
2003 Extent[i].extLocation = 0;
2005#ifdef UDF_DBG
2006 } else {
2007 UDFPrint(("Broken unallocated space descriptor sequence\n"));
2008#endif // UDF_DBG
2009 }
2010 }
2011 }
2012 UDFMarkSpaceAsXXX(Vcb, (-1), Extent, AS_USED); // mark as used
2014 MyFreePool__(AllocDesc);
2015 }
2016 return status;
2017} // end UDFVerifyFreeSpaceBitmap()
2018
2019/*
2020 process Partition descriptor
2021 */
2024 PVCB Vcb,
2025 int8* Buf
2026 )
2027{
2028 PartitionDesc *p = (PartitionDesc *)Buf;
2029 uint32 i;
2030 OSSTATUS RC;
2032 UDFPrint(("UDF: Pard Descr:\n"));
2033 UDFPrint((" volDescSeqNum = %x\n", p->volDescSeqNum));
2034 UDFPrint((" partitionFlags = %x\n", p->partitionFlags));
2035 UDFPrint((" partitionNumber = %x\n", p->partitionNumber));
2036 UDFPrint((" accessType = %x\n", p->accessType));
2037 UDFPrint((" partitionStartingLocation = %x\n", p->partitionStartingLocation));
2038 UDFPrint((" partitionLength = %x\n", p->partitionLength));
2039 // There is nothing interesting to comment here
2040 // Just look at Names & Messages....
2041 for (i=0; i<Vcb->PartitionMaps; i++) {
2042 UDFPrint(("Searching map: (%d == %d)\n",
2043 Vcb->Partitions[i].PartitionNum, (p->partitionNumber) ));
2044 if(Vcb->Partitions[i].PartitionNum == (p->partitionNumber)) {
2045 Found = TRUE;
2046 Vcb->Partitions[i].PartitionRoot = p->partitionStartingLocation + Vcb->FirstLBA;
2047 Vcb->Partitions[i].PartitionLen = p->partitionLength;
2048 Vcb->Partitions[i].UspaceBitmap = 0xFFFFFFFF;
2049 Vcb->Partitions[i].FspaceBitmap = 0xFFFFFFFF;
2050 Vcb->Partitions[i].AccessType = p->accessType;
2051 UDFPrint(("Access mode %x\n", p->accessType));
2052 if(p->accessType == PARTITION_ACCESS_WO) {
2053 Vcb->CDR_Mode = TRUE;
2054// Vcb->Partitions[i].PartitionLen = Vcb->LastPossibleLBA - p->partitionStartingLocation;
2055 } else if(p->accessType < PARTITION_ACCESS_WO) {
2056 // Soft-read-only volume
2057 UDFPrint(("Soft Read-only volume\n"));
2059 Vcb->UserFSFlags |= UDF_USER_FS_FLAGS_PART_RO;
2060 } else if(p->accessType > PARTITION_ACCESS_MAX_KNOWN) {
2062 }
2063
2064 if(!strcmp((int8*)&(p->partitionContents.ident), PARTITION_CONTENTS_NSR02) ||
2065 !strcmp((int8*)&(p->partitionContents.ident), PARTITION_CONTENTS_NSR03))
2066 {
2068
2069 phd = (PPARTITION_HEADER_DESC)(p->partitionContentsUse);
2070#ifdef UDF_DBG
2072 UDFPrint(("unallocatedSpaceTable (part %d)\n", i));
2073#endif // UDF_DBG
2075 Vcb->Partitions[i].UspaceBitmap =
2077 UDFPrint(("unallocatedSpaceBitmap (part %d) @ %x\n",
2078 i, Vcb->Partitions[i].UspaceBitmap ));
2079 }
2080#ifdef UDF_DBG
2082 UDFPrint(("partitionIntegrityTable (part %d)\n", i));
2083 if(phd->freedSpaceTable.extLength)
2084 UDFPrint(("freedSpaceTable (part %d)\n", i));
2085#endif // UDF_DBG
2086 if(phd->freedSpaceBitmap.extLength) {
2087 Vcb->Partitions[i].FspaceBitmap =
2089 UDFPrint(("freedSpaceBitmap (part %d)\n", i));
2090 }
2091 RC = UDFBuildFreeSpaceBitmap(Vcb, i, phd, 0);
2092 //Vcb->Modified = FALSE;
2095 if(!OS_SUCCESS(RC))
2096 return RC;
2097
2098 if ((Vcb->Partitions[i].PartitionType == UDF_VIRTUAL_MAP15) ||
2099 (Vcb->Partitions[i].PartitionType == UDF_VIRTUAL_MAP20)) {
2100 RC = UDFLoadVAT(Vcb, i);
2101 if(!OS_SUCCESS(RC))
2102 return RC;
2103 WCacheFlushAll__(&(Vcb->FastCache), Vcb);
2104 WCacheSetMode__(&(Vcb->FastCache), WCACHE_MODE_R);
2105 Vcb->LastModifiedTrack = 0;
2106 }
2107 }
2108 }
2109 }
2110#ifdef UDF_DBG
2111 if(!Found) {
2112 UDFPrint(("Partition (%d) not found in partition map\n", (p->partitionNumber) ));
2113 } else {
2114 UDFPrint(("Partition (%d:%d type %x) starts at physical %x, length %x\n",
2115 p->partitionNumber, i-1, Vcb->Partitions[i-1].PartitionType,
2116 Vcb->Partitions[i-1].PartitionRoot, Vcb->Partitions[i-1].PartitionLen));
2117 }
2118#endif // UDF_DBG
2119 return STATUS_SUCCESS;
2120} // end UDFLoadPartDesc()
2121
2122/*
2123 process Partition descriptor
2124 */
2127 PVCB Vcb,
2128 int8* Buf
2129 )
2130{
2131 PartitionDesc *p = (PartitionDesc *)Buf;
2132 uint32 i;
2133 OSSTATUS RC;
2135 UDFPrint(("UDF: Verify Part Descr:\n"));
2136 UDFPrint((" volDescSeqNum = %x\n", p->volDescSeqNum));
2137 UDFPrint((" partitionFlags = %x\n", p->partitionFlags));
2138 UDFPrint((" partitionNumber = %x\n", p->partitionNumber));
2139 UDFPrint((" accessType = %x\n", p->accessType));
2140 UDFPrint((" partitionStartingLocation = %x\n", p->partitionStartingLocation));
2141 UDFPrint((" partitionLength = %x\n", p->partitionLength));
2142 // There is nothing interesting to comment here
2143 // Just look at Names & Messages....
2144 for (i=0; i<Vcb->PartitionMaps; i++) {
2145 UDFPrint(("Searching map: (%d == %d)\n",
2146 Vcb->Partitions[i].PartitionNum, (p->partitionNumber) ));
2147 if(Vcb->Partitions[i].PartitionNum == (p->partitionNumber)) {
2148 Found = TRUE;
2149 if(Vcb->Partitions[i].PartitionRoot != p->partitionStartingLocation + Vcb->FirstLBA)
2151 if(Vcb->Partitions[i].PartitionLen !=
2152 min(p->partitionLength,
2153 Vcb->LastPossibleLBA - Vcb->Partitions[i].PartitionRoot)) /* sectors */
2155// Vcb->Partitions[i].UspaceBitmap = 0xFFFFFFFF;
2156// Vcb->Partitions[i].FspaceBitmap = 0xFFFFFFFF;
2157 if(Vcb->Partitions[i].AccessType != p->accessType)
2159 UDFPrint(("Access mode %x\n", p->accessType));
2160 if(p->accessType == PARTITION_ACCESS_WO) {
2161 if(Vcb->CDR_Mode != TRUE)
2163// Vcb->Partitions[i].PartitionLen = Vcb->LastPossibleLBA - p->partitionStartingLocation;
2164 } else if(p->accessType < PARTITION_ACCESS_WO) {
2165 // Soft-read-only volume
2166 UDFPrint(("Soft Read-only volume\n"));
2167 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY))
2169 } else if(p->accessType > PARTITION_ACCESS_MAX_KNOWN) {
2171 }
2172
2173 if(!strcmp((int8*)&(p->partitionContents.ident), PARTITION_CONTENTS_NSR02) ||
2174 !strcmp((int8*)&(p->partitionContents.ident), PARTITION_CONTENTS_NSR03))
2175 {
2177
2178 phd = (PPARTITION_HEADER_DESC)(p->partitionContentsUse);
2179#ifdef UDF_DBG
2181 UDFPrint(("unallocatedSpaceTable (part %d)\n", i));
2182#endif // UDF_DBG
2184 if(Vcb->Partitions[i].UspaceBitmap ==
2186 UDFPrint(("Warning: both USpaceBitmaps have same location\n"));
2187 }
2188 UDFPrint(("unallocatedSpaceBitmap (part %d) @ %x\n",
2189 i, Vcb->Partitions[i].UspaceBitmap ));
2190 }
2191#ifdef UDF_DBG
2193 UDFPrint(("partitionIntegrityTable (part %d)\n", i));
2194 if(phd->freedSpaceTable.extLength)
2195 UDFPrint(("freedSpaceTable (part %d)\n", i));
2196#endif // UDF_DBG
2197 if(phd->freedSpaceBitmap.extLength) {
2198 if(Vcb->Partitions[i].FspaceBitmap ==
2200 UDFPrint(("Warning: both FSpaceBitmaps have same location\n"));
2201 }
2202 UDFPrint(("freedSpaceBitmap (part %d)\n", i));
2203 }
2204 RC = UDFVerifyFreeSpaceBitmap(Vcb, i, phd, 0);
2205 //Vcb->Modified = FALSE;
2206 //UDFPreClrModified(Vcb);
2207 //UDFClrModified(Vcb);
2208 if(!OS_SUCCESS(RC))
2209 return RC;
2210
2211 if ((Vcb->Partitions[i].PartitionType == UDF_VIRTUAL_MAP15) ||
2212 (Vcb->Partitions[i].PartitionType == UDF_VIRTUAL_MAP20)) {
2213/* RC = UDFLoadVAT(Vcb, i);
2214 if(!OS_SUCCESS(RC))
2215 return RC;
2216 WCacheFlushAll__(&(Vcb->FastCache), Vcb);
2217 WCacheSetMode__(&(Vcb->FastCache), WCACHE_MODE_R);
2218 Vcb->LastModifiedTrack = 0;*/
2219 }
2220 }
2221 }
2222 }
2223#ifdef UDF_DBG
2224 if(!Found) {
2225 UDFPrint(("Partition (%d) not found in partition map\n", (p->partitionNumber) ));
2226 } else {
2227 UDFPrint(("Partition (%d:%d type %x) starts at physical %x, length %x\n",
2228 p->partitionNumber, i-1, Vcb->Partitions[i-1].PartitionType,
2229 Vcb->Partitions[i-1].PartitionRoot, Vcb->Partitions[i-1].PartitionLen));
2230 }
2231#endif // UDF_DBG
2232 return STATUS_SUCCESS;
2233} // end UDFVerifyPartDesc()
2234
2235/*
2236 This routine scans VDS & fills special array with Desc locations
2237 */
2240 IN PVCB Vcb,
2241 IN uint32 block,
2242 IN uint32 lastblock,
2243 IN PUDF_VDS_RECORD vds,
2244 IN int8* Buf
2245 )
2246{
2248 GenericDesc* gd;
2249 BOOLEAN done=FALSE;
2250 uint32 vdsn;
2251 uint16 ident;
2252
2253 UDFPrint(("UDF: Read VDS (%x - %x)\n", block, lastblock ));
2254 // Read the main descriptor sequence
2255 for (;(!done && block <= lastblock); block++)
2256 {
2258 if(!OS_SUCCESS(status))
2259 return status;
2260 UDFRegisterFsStructure(Vcb, block, Vcb->BlockSize);
2261
2262 // Process each descriptor (ISO 13346 3/8.3-8.4)
2263 gd = (struct GenericDesc *)Buf;
2264 vdsn = gd->volDescSeqNum;
2265 UDFPrint(("LBA %x, Ident = %x, vdsn = %x\n", block, ident, vdsn ));
2266 switch (ident)
2267 {
2268 case TID_PRIMARY_VOL_DESC: // ISO 13346 3/10.1
2270 {
2271 vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum = vdsn;
2272 vds[VDS_POS_PRIMARY_VOL_DESC].block = block;
2273 }
2274 break;
2275 case TID_VOL_DESC_PTR: // ISO 13346 3/10.3
2276 struct VolDescPtr* pVDP;
2277 if(vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum)
2278 {
2280 vds[VDS_POS_VOL_DESC_PTR].block = block;
2281 vds[VDS_POS_RECURSION_COUNTER].volDescSeqNum++;
2283 UDFPrint(("too long multipart VDS -> abort\n"));
2285 }
2286 pVDP = (struct VolDescPtr*)Buf;
2287 UDFPrint(("multipart VDS...\n"));
2289 pVDP->nextVolDescSeqExt.extLocation + (pVDP->nextVolDescSeqExt.extLocation >> Vcb->BlockSizeBits),
2290 vds, Buf);
2291 }
2292 break;
2293 case TID_IMP_USE_VOL_DESC: // ISO 13346 3/10.4
2295 {
2296 vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum = vdsn;
2297 vds[VDS_POS_IMP_USE_VOL_DESC].block = block;
2298 }
2299 break;
2300 case TID_PARTITION_DESC: // ISO 13346 3/10.5
2302 vds[VDS_POS_PARTITION_DESC].block = block;
2303 break;
2304 case TID_LOGICAL_VOL_DESC: // ISO 13346 3/10.6
2305 case TID_ADAPTEC_LOGICAL_VOL_DESC: // Adaptec Compressed UDF extesion
2307 {
2308 vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum = vdsn;
2309 vds[VDS_POS_LOGICAL_VOL_DESC].block = block;
2310 }
2311 break;
2312 case TID_UNALLOC_SPACE_DESC: // ISO 13346 3/10.8
2314 {
2315 vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum = vdsn;
2316 vds[VDS_POS_UNALLOC_SPACE_DESC].block = block;
2317 }
2318 break;
2319 case TID_TERMINATING_DESC: // ISO 13346 3/10.9
2320 vds[VDS_POS_TERMINATING_DESC].block = block;
2321 done = TRUE;
2322 break;
2323 }
2324 }
2325 return STATUS_SUCCESS;
2326} // UDFReadVDS()
2327
2330 IN PVCB Vcb,
2331 int8* Buf
2332 )
2333{
2334#ifdef UDF_DBG
2335 ImpUseVolDesc* iuvd = (ImpUseVolDesc*)Buf;
2336 ImpUseVolDescImpUse* iuvdiu = (ImpUseVolDescImpUse*)&(iuvd->impUse);
2337 UDFPrint(("UDF: Imp Use Vol Desc:\n"));
2338 UDFPrint((" volDescSeqNum = %x\n", iuvd->volDescSeqNum));
2339 UDFPrint(("UDF: Imp Use Vol Desc Imp Use:\n"));
2340 KdDump(iuvdiu, sizeof(ImpUseVolDescImpUse));
2341#endif
2342 return STATUS_SUCCESS;
2343} // UDFLoadImpUseVolDesc()
2344
2347 IN PVCB Vcb,
2348 int8* Buf
2349 )
2350{
2351 UDFPrint(("UDF: Unallocated Space Desc:\n"));
2352// UnallocatedSpaceDesc* usd = (UnallocatedSpaceDesc*)Buf;
2353 return STATUS_SUCCESS;
2354} // UDFLoadImpUseVolDesc()
2355
2356/*
2357 Process a main/reserve volume descriptor sequence.
2358*/
2362 IN PVCB Vcb,
2363 IN uint32 block,
2364 IN uint32 lastblock,
2365 OUT lb_addr *fileset
2366 )
2367{
2369 int8* Buf = (int8*)MyAllocatePool__(NonPagedPool,Vcb->BlockSize);
2371// GenericDesc *gd;
2372 uint32 i,j;
2373 uint16 ident;
2374 int8* Buf2 = NULL;
2375
2376 _SEH2_TRY {
2379 if(!OS_SUCCESS(RC = UDFReadVDS(Vcb, block, lastblock, (PUDF_VDS_RECORD)&vds, Buf)))
2380 try_return(RC);
2381 // walk through Vol Desc Sequence according to locations gained by
2382 // UDFReadVDS() & do some procesing for each one
2383 // It is very simple dispath routine...
2384 for (i=0; i<VDS_POS_LENGTH; i++)
2385 {
2386 if(vds[i].block)
2387 {
2388 if(!OS_SUCCESS(RC = UDFReadTagged(Vcb, Buf, vds[i].block, vds[i].block, &ident)))
2389 try_return(RC);
2390 UDFRegisterFsStructure(Vcb, vds[i].block, Vcb->BlockSize);
2391
2393 UDFLoadPVolDesc(Vcb,Buf);
2394 if(!Vcb->PVolDescAddr.block) {
2395 Vcb->PVolDescAddr = vds[i];
2396 } else {
2397 Vcb->PVolDescAddr2 = vds[i];
2398 }
2399 } else
2401 RC = UDFLoadLogicalVol(DeviceObject,Vcb, Buf, fileset);
2402 if(!OS_SUCCESS(RC)) try_return(RC);
2403 } else
2404
2407 } else
2410 } else
2411
2413 {
2414 Buf2 = (int8*)MyAllocatePool__(NonPagedPool,Vcb->BlockSize);
2416 RC = UDFLoadPartDesc(Vcb,Buf);
2417 if(!OS_SUCCESS(RC)) try_return(RC);
2418 for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++)
2419 {
2420 RC = UDFReadTagged(Vcb,Buf2, j, j, &ident);
2421 if(!OS_SUCCESS(RC)) try_return(RC);
2422 UDFRegisterFsStructure(Vcb, j, Vcb->BlockSize);
2423// gd = (struct GenericDesc *)Buf2;
2424 if(ident == TID_PARTITION_DESC) {
2425 RC = UDFLoadPartDesc(Vcb,Buf2);
2426 if(!OS_SUCCESS(RC)) try_return(RC);
2427 } else if(ident == TID_UNALLOC_SPACE_DESC) {
2429 //Vcb->Modified = FALSE;
2432 if(!OS_SUCCESS(RC))
2433 try_return(RC);
2434 }
2435 }
2436 MyFreePool__(Buf2);
2437 Buf2 = NULL;
2438 }
2439 } else {
2441 RC = UDFLoadBogusLogicalVol(DeviceObject,Vcb, Buf, fileset);
2442 if(!OS_SUCCESS(RC)) try_return(RC);
2443 }
2444 }
2445 }
2446
2447try_exit: NOTHING;
2448
2449 } _SEH2_FINALLY {
2450 if(Buf) MyFreePool__(Buf);
2451 if(Buf2) MyFreePool__(Buf2);
2452 } _SEH2_END;
2453
2454 return RC;
2455} // end UDFProcessSequence()
2456
2457/*
2458 Verifies a main/reserve volume descriptor sequence.
2459*/
2463 IN PVCB Vcb,
2464 IN uint32 block,
2465 IN uint32 lastblock,
2466 OUT lb_addr *fileset
2467 )
2468{
2470 int8* Buf = (int8*)MyAllocatePool__(NonPagedPool,Vcb->BlockSize);
2472// GenericDesc *gd;
2473 uint32 i,j;
2474 uint16 ident;
2475 int8* Buf2 = NULL;
2476
2477 _SEH2_TRY {
2479 if(!block) try_return (RC = STATUS_SUCCESS);
2481 if(!OS_SUCCESS(RC = UDFReadVDS(Vcb, block, lastblock, (PUDF_VDS_RECORD)&vds, Buf)))
2482 try_return(RC);
2483
2484 for (i=0; i<VDS_POS_LENGTH; i++)
2485 {
2486 if(vds[i].block)
2487 {
2488 if(!OS_SUCCESS(RC = UDFReadTagged(Vcb, Buf, vds[i].block, vds[i].block, &ident)))
2489 try_return(RC);
2490 UDFRegisterFsStructure(Vcb, vds[i].block, Vcb->BlockSize);
2491
2492 /* if(i == VDS_POS_PRIMARY_VOL_DESC)
2493 UDFLoadPVolDesc(Vcb,Buf);
2494 else if(i == VDS_POS_LOGICAL_VOL_DESC) {
2495 RC = UDFLoadLogicalVol(DeviceObject,Vcb, Buf, fileset);
2496 if(!OS_SUCCESS(RC)) try_return(RC);
2497 }
2498 else*/ if(i == VDS_POS_PARTITION_DESC)
2499 {
2500 Buf2 = (int8*)MyAllocatePool__(NonPagedPool,Vcb->BlockSize);
2502 RC = UDFVerifyPartDesc(Vcb,Buf);
2503 if(!OS_SUCCESS(RC)) try_return(RC);
2504 for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++)
2505 {
2506 RC = UDFReadTagged(Vcb,Buf2, j, j, &ident);
2507 if(!OS_SUCCESS(RC)) try_return(RC);
2508 UDFRegisterFsStructure(Vcb, j, Vcb->BlockSize);
2509// gd = (struct GenericDesc *)Buf2;
2510 if(ident == TID_PARTITION_DESC) {
2511 RC = UDFVerifyPartDesc(Vcb,Buf2);
2512 if(!OS_SUCCESS(RC)) try_return(RC);
2513 } else if(ident == TID_UNALLOC_SPACE_DESC) {
2515 Vcb->Modified = FALSE;
2516 if(!OS_SUCCESS(RC))
2517 try_return(RC);
2518 }
2519 }
2520 MyFreePool__(Buf2);
2521 Buf2 = NULL;
2522 }
2523 }
2524 }
2525try_exit: NOTHING;
2526
2527 } _SEH2_FINALLY {
2528 if(Buf) MyFreePool__(Buf);
2529 if(Buf2) MyFreePool__(Buf2);
2530 } _SEH2_END;
2531
2532 return RC;
2533} // end UDFVerifySequence()
2534
2535/*
2536 remember some useful info about FileSet & RootDir location
2537 */
2538void
2540 IN PVCB Vcb,
2541 IN PFILE_SET_DESC fset,
2542 OUT lb_addr *root,
2543 OUT lb_addr *sysstream
2544 )
2545{
2546 *root = fset->rootDirectoryICB.extLocation;
2547 Vcb->SerialNumber = fset->descTag.tagSerialNum;
2548 UDFPrint(("Rootdir at block=%x, partition=%d\n",
2549 root->logicalBlockNum, root->partitionReferenceNum));
2550 if(sysstream) {
2551 *sysstream = fset->streamDirectoryICB.extLocation;
2552 UDFPrint(("SysStream at block=%x, partition=%d\n",
2553 sysstream->logicalBlockNum, sysstream->partitionReferenceNum));
2554 }
2555#define CUR_IDENT_SZ (sizeof(fset->logicalVolIdent))
2556 if (Vcb->VolIdent.Buffer) {
2557 MyFreePool__(Vcb->VolIdent.Buffer);
2558 }
2559 UDFGetDstring(&(Vcb->VolIdent), (dstring*)&(fset->logicalVolIdent), CUR_IDENT_SZ);
2560#undef CUR_IDENT_SZ
2561 UDFPrint(("volIdent[] = '%ws'\n", Vcb->VolIdent.Buffer));
2562 // Get current UDF revision
2563 // Get Read-Only flags
2564 UDFReadEntityID_Domain(Vcb, &(fset->domainIdent));
2565
2566} // end UDFLoadFileset()
2567
2570 IN PVCB Vcb,
2571 IN uint32 Lba
2572 )
2573{
2574 ULONG j;
2576 // Check if it is known bad sequence
2577 for(j=0; j<Vcb->BadSeqLocIndex; j++) {
2578 if(Vcb->BadSeqLoc[j] == Lba) {
2579 RC = Vcb->BadSeqStatus[j];
2580 break;
2581 }
2582 }
2583 return RC;
2584} // end UDFIsCachedBadSequence()
2585
2586VOID
2588 IN PVCB Vcb,
2589 IN uint32 Lba,
2590 IN OSSTATUS RC
2591 )
2592{
2593 int j;
2595 return;
2596 // Remenber bad sequence
2597 j = Vcb->BadSeqLocIndex;
2598 Vcb->BadSeqLocIndex++;
2599 Vcb->BadSeqLoc[j] = Lba;
2600 Vcb->BadSeqStatus[j] = RC;
2601} // end UDFRememberBadSequence()
2602
2603/*
2604 load partition info
2605 */
2609 IN PVCB Vcb,
2610 OUT lb_addr *fileset
2611 )
2612{
2615 AnchorVolDescPtr *anchor;
2616 uint16 ident;
2617 int8* Buf = (int8*)MyAllocatePool__(NonPagedPool,Vcb->BlockSize);
2618 uint32 main_s, main_e;
2619 uint32 reserve_s, reserve_e;
2620 int i;
2621
2622 if(!Buf) return STATUS_INSUFFICIENT_RESOURCES;
2623 // walk through all available Anchors & load data
2624 for (i=0; i<MAX_ANCHOR_LOCATIONS; i++)
2625 {
2626 if(Vcb->Anchor[i] && (OS_SUCCESS(UDFReadTagged(Vcb, Buf,
2627 Vcb->Anchor[i], Vcb->Anchor[i] - Vcb->FirstLBA, &ident))))
2628 {
2629 anchor = (AnchorVolDescPtr *)Buf;
2630
2631 // Locate the main sequence
2632 main_s = ( anchor->mainVolDescSeqExt.extLocation );
2633 main_e = ( anchor->mainVolDescSeqExt.extLength );
2634 main_e = main_e >> Vcb->BlockSizeBits;
2635 main_e += main_s;
2636
2637 // Locate the reserve sequence
2638 reserve_s = (anchor->reserveVolDescSeqExt.extLocation);
2639 reserve_e = (anchor->reserveVolDescSeqExt.extLength);
2640 reserve_e = reserve_e >> Vcb->BlockSizeBits;
2641 reserve_e += reserve_s;
2642
2643 // Check if it is known bad sequence
2644 RC = UDFIsCachedBadSequence(Vcb, main_s);
2645 if(OS_SUCCESS(RC)) {
2646 // Process the main & reserve sequences
2647 // responsible for finding the PartitionDesc(s)
2648 UDFPrint(("-----------------------------------\n"));
2649 UDFPrint(("UDF: Main sequence:\n"));
2650 RC = UDFProcessSequence(DeviceObject, Vcb, main_s, main_e, fileset);
2651 }
2652
2653 if(!OS_SUCCESS(RC)) {
2654 // Remenber bad sequence
2655 UDFRememberBadSequence(Vcb, main_s, RC);
2656
2657 UDFPrint(("-----------------------------------\n"));
2658 UDFPrint(("UDF: Main sequence failed.\n"));
2659 UDFPrint(("UDF: Reserve sequence\n"));
2660 if(Vcb->LVid) MyFreePool__(Vcb->LVid);
2661 Vcb->LVid = NULL;
2662
2663 RC2 = UDFIsCachedBadSequence(Vcb, reserve_s);
2664 if(OS_SUCCESS(RC2)) {
2665 RC2 = UDFProcessSequence(DeviceObject, Vcb, reserve_s, reserve_e, fileset);
2666 }
2667
2668 if(OS_SUCCESS(RC2)) {
2669 UDFPrint(("-----------------------------------\n"));
2670 Vcb->VDS2_Len = reserve_e - reserve_s;
2671 Vcb->VDS2 = reserve_s;
2672 RC = STATUS_SUCCESS;
2673 // Vcb is already Zero-filled
2674// Vcb->VDS1_Len = 0;
2675// Vcb->VDS1 = 0;
2676 break;
2677 } else {
2678 // This is also bad sequence. Remenber it too
2679 UDFRememberBadSequence(Vcb, reserve_s, RC);
2680 }
2681 } else {
2682 // remember these values for umount__
2683 Vcb->VDS1_Len = main_e - main_s;
2684 Vcb->VDS1 = main_s;
2685/* if(Vcb->LVid) MyFreePool__(Vcb->LVid);
2686 Vcb->LVid = NULL;*/
2687 if(OS_SUCCESS(UDFVerifySequence(DeviceObject, Vcb, reserve_s, reserve_e, fileset)))
2688 {
2689 UDFPrint(("-----------------------------------\n"));
2690 Vcb->VDS2_Len = reserve_e - reserve_s;
2691 Vcb->VDS2 = reserve_s;
2692 break;
2693 } else {
2694 UDFPrint(("UDF: Reserve sequence verification failed.\n"));
2695 switch(Vcb->PartitialDamagedVolumeAction) {
2697 UDFPrint(("UDF: Switch to r/o mode.\n"));
2699 break;
2701 UDFPrint(("UDF: Switch to raw mount mode, return UNRECOGNIZED_VOLUME.\n"));
2702 Vcb->VCBFlags |= UDF_VCB_FLAGS_RAW_DISK;
2704 break;
2706 default:
2707 UDFPrint(("UDF: Keep r/w mode for your own risk.\n"));
2708 break;
2709 }
2710 }
2711 break;
2712 }
2713 }
2714 }
2715
2716 if(Vcb->SparingCount &&
2717 (Vcb->NoFreeRelocationSpaceVolumeAction != UDF_PART_DAMAGED_RW)) {
2718 UDFPrint(("UDF: No free Sparing Entries -> Switch to r/o mode.\n"));
2720 }
2721
2722 if(i == sizeof(Vcb->Anchor)/sizeof(int)) {
2723 UDFPrint(("No Anchor block found\n"));
2725#ifdef UDF_DBG
2726 } else {
2727 UDFPrint(("Using anchor in block %x\n", Vcb->Anchor[i]));
2728#endif // UDF_DBG
2729 }
2730 MyFreePool__(Buf);
2731 return RC;
2732} // end UDFLoadPartition()
2733
2734/*
2735 This routine scans FileSet sequence & returns pointer to last valid
2736 FileSet
2737 */
2740 IN PVCB Vcb,
2741 IN lb_addr *Addr, // Addr for the 1st FileSet
2742 IN OUT PFILE_SET_DESC FileSetDesc
2743 )
2744{
2746 uint32 relLocExt = Addr->logicalBlockNum;
2747 uint32 locExt = UDFPartLbaToPhys(Vcb, Addr);
2748 uint16 Ident;
2749 uint32 relPrevExt, prevExt;
2750
2751 relPrevExt, prevExt = NULL;
2752 FileSetDesc->nextExt.extLength = 1; // ;)
2753 // walk through FileSet chain
2754 // we've just pre-init'd extent length to read 1st FileSet
2755 while(FileSetDesc->nextExt.extLength) {
2756 status = UDFReadTagged(Vcb, (int8*)FileSetDesc, locExt, relLocExt, &Ident);
2757 if(!OS_SUCCESS(status)) {
2758 FileSetDesc->nextExt.extLength = 0;
2759 return status;
2760 }
2761 UDFRegisterFsStructure(Vcb, locExt, Vcb->BlockSize);
2762 if((locExt == LBA_OUT_OF_EXTENT) || (Ident != TID_FILE_SET_DESC)) {
2763 // try to read previous FileSet
2764 if(!prevExt) return STATUS_UNRECOGNIZED_VOLUME;
2765 status = UDFReadTagged(Vcb, (int8*)FileSetDesc, prevExt, relLocExt, &Ident);
2766 if(OS_SUCCESS(status)) {
2767 UDFRegisterFsStructure(Vcb, prevExt, Vcb->BlockSize);
2768 }
2769 return status;
2770 }
2771 prevExt = locExt;
2772 relPrevExt = relLocExt;
2773 locExt = UDFPartLbaToPhys(Vcb, &(FileSetDesc->nextExt.extLocation));
2774 }
2775 return STATUS_SUCCESS;
2776} // end UDFFindLastFileSet()
2777
2778/*
2779 This routine reads all sparing tables & stores them in contiguos memory
2780 space
2781 */
2784 IN PVCB Vcb,
2786 )
2787{
2788 PSPARING_MAP RelocMap;
2789 PSPARING_MAP NewRelocMap;
2791 uint32 i=0, BC, BC2;
2792 PSPARING_TABLE SparTable;
2793 uint32 TabSize, NewSize;
2795 uint32 SparTableLoc;
2796#ifdef UDF_TRACK_FS_STRUCTURES
2797 uint32 j;
2798#endif //UDF_TRACK_FS_STRUCTURES
2799 uint32 n,m;
2800 BOOLEAN merged;
2801
2802 Vcb->SparingCountFree = -1;
2803
2804 UDFPrint(("UDF: Sparable Part Map:\n"));
2805 Vcb->SparingTableLength = PartMap->sizeSparingTable;
2806 BC = (PartMap->sizeSparingTable >> Vcb->BlockSizeBits) + 1;
2807 UDFPrint((" partitionMapType = %x\n", PartMap->partitionMapType));
2808 UDFPrint((" partitionMapLength = %x\n", PartMap->partitionMapLength));
2809 UDFPrint((" volSeqNum = %x\n", PartMap->volSeqNum));
2810 UDFPrint((" partitionNum = %x\n", PartMap->partitionNum));
2811 UDFPrint((" packetLength = %x\n", PartMap->packetLength));
2812 UDFPrint((" numSparingTables = %x\n", PartMap->numSparingTables));
2813 UDFPrint((" sizeSparingTable = %x\n", PartMap->sizeSparingTable));
2814 SparTable = (PSPARING_TABLE)MyAllocatePool__(NonPagedPool, BC*Vcb->BlockSize);
2815 if(!SparTable) return STATUS_INSUFFICIENT_RESOURCES;
2816 if(Vcb->SparingTable) {
2817 // if a part of Sparing Table is already loaded,
2818 // update it with data from another one
2819 RelocMap = Vcb->SparingTable;
2820 TabSize = Vcb->SparingCount * sizeof(SPARING_ENTRY);
2821 } else {
2822 // do some init to load first part of Sparing Table
2824 if(!RelocMap) {
2825 MyFreePool__(SparTable);
2827 }
2828 TabSize = RELOC_MAP_GRAN;
2829 Vcb->SparingBlockSize = PartMap->packetLength;
2830 }
2831 // walk through all available Sparing Tables
2832 for(i=0;i<PartMap->numSparingTables;i++) {
2833 // read (next) table
2834 SparTableLoc = ((uint32*)(PartMap+1))[i];
2835 for(n=0; n<Vcb->SparingTableCount; n++) {
2836 if(Vcb->SparingTableLoc[i] == SparTableLoc) {
2837 UDFPrint((" already processed @%x\n",
2838 SparTableLoc
2839 ));
2840 continue;
2841 }
2842 }
2843 status = UDFReadSectors(Vcb, FALSE, SparTableLoc, 1, FALSE, (int8*)SparTable, &ReadBytes);
2844 // tag should be set to TID_UNUSED_DESC
2845 if(OS_SUCCESS(status) && (SparTable->descTag.tagIdent == TID_UNUSED_DESC)) {
2846
2847 UDFRegisterFsStructure(Vcb, SparTableLoc, Vcb->BlockSize);
2848 BC2 = ((sizeof(SPARING_TABLE) +
2849 SparTable->reallocationTableLen*sizeof(SparingEntry) +
2850 Vcb->BlockSize-1)
2851 >> Vcb->BlockSizeBits);
2852 if(BC2 > BC) {
2853 UDFPrint((" sizeSparingTable @%x too long: %x > %x\n",
2854 SparTableLoc, BC2, BC
2855 ));
2856 continue;
2857 }
2858 status = UDFReadSectors(Vcb, FALSE, SparTableLoc,
2859 BC2, FALSE, (int8*)SparTable, &ReadBytes);
2860 UDFRegisterFsStructure(Vcb, SparTableLoc, BC2<<Vcb->BlockSizeBits);
2861
2862 if(!OS_SUCCESS(status)) {
2863 UDFPrint((" Error reading sizeSparingTable @%x (%x)\n",
2864 SparTableLoc, BC2
2865 ));
2866 continue;
2867 }
2868 // process sparing table
2869 NewSize = sizeof(SparingEntry)*SparTable->reallocationTableLen;
2870 TabSize = MyReallocPool__((int8*)RelocMap, TabSize, (int8**)&RelocMap, TabSize+NewSize);
2871 if(!TabSize) {
2872 MyFreePool__(SparTable);
2874 }
2875
2876#ifdef UDF_TRACK_FS_STRUCTURES
2877 for(j=0; j<SparTable->reallocationTableLen; j++) {
2878 UDFRegisterFsStructure(Vcb, ((SparingEntry*)(SparTable+1))[j].mappedLocation, Vcb->WriteBlockSize);
2879 }
2880#endif //UDF_TRACK_FS_STRUCTURES
2881
2882 Vcb->SparingTableLoc[Vcb->SparingTableCount] = SparTableLoc;
2883 Vcb->SparingTableCount++;
2884
2885 NewRelocMap = (PSPARING_MAP)(SparTable+1);
2886 for(n=0; n<SparTable->reallocationTableLen; n++) {
2887 merged = TRUE;
2888 for(m=0; m<Vcb->SparingCount; m++) {
2889 if(RelocMap[m].mappedLocation == NewRelocMap[n].mappedLocation) {
2890 UDFPrint((" dup @%x (%x) vs @%x (%x)\n",
2891 RelocMap[m].origLocation, RelocMap[m].mappedLocation,
2892 NewRelocMap[m].origLocation, NewRelocMap[m].mappedLocation));
2893 merged = FALSE;
2894 }
2895 if((RelocMap[m].origLocation == NewRelocMap[n].origLocation) &&
2896 (RelocMap[m].mappedLocation != NewRelocMap[n].mappedLocation) &&
2897 (RelocMap[m].origLocation != SPARING_LOC_AVAILABLE) &&
2898 (RelocMap[m].origLocation != SPARING_LOC_CORRUPTED)) {
2899 UDFPrint((" conflict @%x (%x) vs @%x (%x)\n",
2900 RelocMap[m].origLocation, RelocMap[m].mappedLocation,
2901 NewRelocMap[n].origLocation, NewRelocMap[n].mappedLocation));
2902 merged = FALSE;
2903 }
2904 }
2905 if(merged) {
2906 RelocMap[Vcb->SparingCount] = NewRelocMap[n];
2907 UDFPrint((" reloc %x -> %x\n",
2908 RelocMap[Vcb->SparingCount].origLocation, RelocMap[Vcb->SparingCount].mappedLocation));
2909 Vcb->SparingCount++;
2910 if(RelocMap[Vcb->SparingCount].origLocation == SPARING_LOC_AVAILABLE) {
2911 Vcb->NoFreeRelocationSpaceVolumeAction = UDF_PART_DAMAGED_RW;
2912 }
2913 }
2914 }
2915
2916/*
2917 RtlCopyMemory((int8*)(RelocMap+Vcb->SparingCount),
2918 (int8*)(SparTable+1), NewSize);
2919 Vcb->SparingCount += NewSize/sizeof(SPARING_ENTRY);
2920*/
2921 if(Vcb->SparingTableCount >= MAX_SPARING_TABLE_LOCATIONS) {
2922 UDFPrint((" too many Sparing Tables\n"));
2923 break;
2924 }
2925 }
2926 }
2927 Vcb->SparingTable = RelocMap;
2928 MyFreePool__(SparTable);
2929 return STATUS_SUCCESS;
2930} // end UDFLoadSparingTable()
2931
2932/*
2933 This routine checks if buffer is ZERO-filled
2934 */
2935BOOLEAN
2937 IN int8* Buf,
2939 )
2940{
2941
2942#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
2943
2944 BOOLEAN RC = FALSE;
2945
2946 uint32 len = Length;
2947 __asm push ecx
2948 __asm push edi
2949
2950 __asm mov ecx,len
2951 __asm mov edi,Buf
2952 __asm xor eax,eax
2953 __asm shr ecx,2
2954 __asm repe scasd
2955 __asm jne short not_all_zeros
2956 __asm mov RC,1
2957
2958not_all_zeros:
2959
2960 __asm pop edi
2961 __asm pop ecx
2962
2963 return RC;
2964
2965#else // _X86_
2966
2967 uint32* tmp = (uint32*)Buf;
2968 uint32 i;
2969
2970 for(i=0; i<Length/4; i++) {
2971 if(tmp[i]) return FALSE;
2972 }
2973 return TRUE;
2974
2975#endif // _X86_
2976
2977} // end UDFCheckZeroBuf()
2978
2979/*
2980 check if this is an UDF-formatted disk
2981*/
2984 IN PDEVICE_OBJECT DeviceObject, // the target device object
2985 IN PVCB Vcb // Volume control block from this DevObj
2986 )
2987{
2990 lb_addr fileset;
2991 PFILE_SET_DESC FileSetDesc = NULL;
2992
2993 int8* Buf = NULL;
2995
2996 UDFPrint(("UDFGetDiskInfoAndVerify\n"));
2997 _SEH2_TRY {
2998
2999 if(!UDFFindAnchor(Vcb)) {
3000 if(Vcb->FsDeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) {
3001 // check if this disc is mountable for CDFS
3002 UDFPrint((" FILE_DEVICE_CD_ROM_FILE_SYSTEM\n"));
3003check_NSR:
3005 if(!(NSRDesc & VRS_ISO9660_FOUND)) {
3006 // no CDFS VRS found
3007 UDFPrint(("UDFGetDiskInfoAndVerify: no CDFS VRS found\n"));
3008 if(!Vcb->TrackMap[Vcb->LastTrackNum].LastLba &&
3009 !Vcb->TrackMap[Vcb->FirstTrackNum].LastLba) {
3010 // such a stupid method of Audio-CD detection...
3011 UDFPrint(("UDFGetDiskInfoAndVerify: set UDF_VCB_FLAGS_RAW_DISK\n"));
3012 Vcb->VCBFlags |= UDF_VCB_FLAGS_RAW_DISK;
3013 }
3014 }
3015 Vcb->NSRDesc = NSRDesc;
3016
3017 Buf = (int8*)MyAllocatePool__(NonPagedPool, 0x10000);
3019 RC = UDFReadData(Vcb, FALSE, 0, 0x10000, FALSE, Buf, &ReadBytes);
3020 if(!OS_SUCCESS(RC))
3023 if(!UDFCheckZeroBuf(Buf,0x10000)) {
3024 UDFPrint(("UDFGetDiskInfoAndVerify: possible FS detected, remove UDF_VCB_FLAGS_RAW_DISK\n"));
3025 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_RAW_DISK;
3026 }
3027 MyFreePool__(Buf);
3028 Buf = NULL;
3029 }
3031 }
3032
3033 RC = UDFLoadPartition(DeviceObject,Vcb,&fileset);
3034 if(!OS_SUCCESS(RC)) {
3035 if(RC == STATUS_UNRECOGNIZED_VOLUME) {
3036 UDFPrint(("UDFGetDiskInfoAndVerify: check NSR presence\n"));
3037 goto check_NSR;
3038 }
3039 try_return(RC);
3040 }
3041
3042 FileSetDesc = (PFILE_SET_DESC)MyAllocatePool__(NonPagedPool,Vcb->BlockSize);
3043 if(!FileSetDesc) try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
3044
3045 RC = UDFFindLastFileSet(Vcb,&fileset,FileSetDesc);
3046 if(!OS_SUCCESS(RC)) try_return(RC);
3047
3048 UDFLoadFileset(Vcb,FileSetDesc, &(Vcb->RootLbAddr), &(Vcb->SysStreamLbAddr));
3049
3050 Vcb->FSBM_OldBitmap = (int8*)DbgAllocatePool(NonPagedPool, Vcb->FSBM_ByteCount);
3051 if(!(Vcb->FSBM_OldBitmap)) try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
3052 RtlCopyMemory(Vcb->FSBM_OldBitmap, Vcb->FSBM_Bitmap, Vcb->FSBM_ByteCount);
3053
3054try_exit: NOTHING;
3055 } _SEH2_FINALLY {
3056 if(FileSetDesc) MyFreePool__(FileSetDesc);
3057 if(Buf) MyFreePool__(Buf);
3058 } _SEH2_END;
3059
3060 return(RC);
3061
3062} // end UDFGetDiskInfoAndVerify()
3063
unsigned char BOOLEAN
LONGLONG UDFTimeToNT(IN PUDF_TIME_STAMP UdfTime)
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
uint32 __fastcall UDFPartEnd(PVCB Vcb, uint32 PartNum)
Definition: alloc.cpp:242
uint32 __fastcall UDFPartLen(PVCB Vcb, uint32 PartNum)
Definition: alloc.cpp:265
uint32 __fastcall UDFGetPartFreeSpace(IN PVCB Vcb, IN uint32 partNum)
Definition: alloc.cpp:1086
uint32 __fastcall UDFPartStart(PVCB Vcb, uint32 PartNum)
Definition: alloc.cpp:222
uint32 UDFPhysLbaToPart(IN PVCB Vcb, IN uint32 PartNum, IN uint32 Addr)
Definition: alloc.cpp:46
uint32 __fastcall UDFGetPartNumByPhysLba(IN PVCB Vcb, IN uint32 Lba)
Definition: alloc.cpp:201
SIZE_T __stdcall UDFGetBitmapLen(uint32 *Bitmap, SIZE_T Offs, SIZE_T Lim)
Definition: alloc.cpp:496
uint32 __fastcall UDFPartLbaToPhys(IN PVCB Vcb, IN lb_addr *Addr)
Definition: alloc.cpp:114
unsigned short uint16
Definition: types.h:30
unsigned int uint32
Definition: types.h:32
unsigned char uint8
Definition: types.h:28
r l[0]
Definition: byte_order.h:168
return Found
Definition: dirsup.c:1270
#define try_return(S)
Definition: cdprocs.h:2179
#define MRW_DMA_OFFSET
Definition: cdrw_hw.h:3199
#define TrackMap_FixMRWAddressing
Definition: cdrw_usr.h:1642
static void xor(unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count)
Definition: crypt_des.c:251
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned long long uint64
Definition: platform.h:18
uint32 lba_t
Definition: platform.h:20
char int8
Definition: platform.h:10
static NTSTATUS ReadBytes(IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
Definition: detect.c:67
#define INTEGRITY_TYPE_OPEN
Definition: ecma_167.h:357
#define TID_UNUSED_DESC
Definition: ecma_167.h:153
#define STD_ID_TEA01
Definition: ecma_167.h:86
#define TID_TERMINATING_DESC
Definition: ecma_167.h:161
#define TID_PRIMARY_VOL_DESC
Definition: ecma_167.h:154
#define TID_IMP_USE_VOL_DESC
Definition: ecma_167.h:157
struct _SPACE_BITMAP_DESC * PSPACE_BITMAP_DESC
#define EXTENT_NOT_RECORDED_ALLOCATED
Definition: ecma_167.h:368
#define TID_ANCHOR_VOL_DESC_PTR
Definition: ecma_167.h:155
#define MAX_VDS_PARTS
Definition: ecma_167.h:231
#define PARTITION_CONTENTS_NSR02
Definition: ecma_167.h:264
#define STD_ID_LEN
Definition: ecma_167.h:71
#define PARTITION_ACCESS_MAX_KNOWN
Definition: ecma_167.h:273
#define TID_EXTENDED_FILE_ENTRY
Definition: ecma_167.h:175
struct _SPACE_BITMAP_DESC SPACE_BITMAP_DESC
struct _FILE_SET_DESC * PFILE_SET_DESC
#define EXTENT_NOT_RECORDED_NOT_ALLOCATED
Definition: ecma_167.h:369
#define STD_ID_NSR03
Definition: ecma_167.h:85
#define EXTENT_NEXT_EXTENT_ALLOCDESC
Definition: ecma_167.h:370
#define EXTENT_RECORDED_ALLOCATED
Definition: ecma_167.h:367
#define TID_LOGICAL_VOL_INTEGRITY_DESC
Definition: ecma_167.h:162
#define TID_FILE_ENTRY
Definition: ecma_167.h:170
#define PARTITION_ACCESS_WO
Definition: ecma_167.h:270
#define TID_UNALLOC_SPACE_DESC
Definition: ecma_167.h:160
#define TID_PARTITION_DESC
Definition: ecma_167.h:158
#define PARTITION_MAP_TYPE_2
Definition: ecma_167.h:302
#define STD_ID_NSR02
Definition: ecma_167.h:84
#define PARTITION_MAP_TYPE_1
Definition: ecma_167.h:301
#define PARTITION_CONTENTS_NSR03
Definition: ecma_167.h:265
#define TID_FILE_SET_DESC
Definition: ecma_167.h:165
uint8 dstring
Definition: ecma_167.h:20
#define STD_ID_CD001
Definition: ecma_167.h:82
#define TID_VOL_DESC_PTR
Definition: ecma_167.h:156
struct _PARTITION_HEADER_DESC * PPARTITION_HEADER_DESC
#define STD_ID_BEA01
Definition: ecma_167.h:80
#define TID_SPACE_BITMAP_DESC
Definition: ecma_167.h:173
#define INTEGRITY_TYPE_CLOSE
Definition: ecma_167.h:358
#define TID_TERMINAL_ENTRY
Definition: ecma_167.h:169
#define TID_LOGICAL_VOL_DESC
Definition: ecma_167.h:159
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define KdDump(a, b)
Definition: env_spec_w32.h:312
#define OS_SUCCESS(a)
Definition: env_spec_w32.h:56
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define DbgFreePool
Definition: env_spec_w32.h:334
#define OSSTATUS
Definition: env_spec_w32.h:57
#define DbgAllocatePool
Definition: env_spec_w32.h:332
#define NonPagedPool
Definition: env_spec_w32.h:307
#define BrutePoint()
Definition: env_spec_w32.h:504
int64 UDFGetExtentLength(IN PEXTENT_MAP Extent)
Definition: extent.cpp:142
OSSTATUS UDFReadExtent(IN PVCB Vcb, IN PEXTENT_INFO ExtInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, OUT int8 *Buffer, OUT PSIZE_T ReadBytes)
Definition: extent.cpp:3021
OSSTATUS UDFFlushAllCachedAllocations(IN PVCB Vcb, IN uint32 AllocClass)
Definition: extent.cpp:1508
void __fastcall UDFPackMapping(IN PVCB Vcb, IN PEXTENT_INFO ExtInfo)
Definition: extent.cpp:2747
PEXTENT_MAP __fastcall UDFMergeMappings(IN PEXTENT_MAP Extent, IN PEXTENT_MAP Extent2)
Definition: extent.cpp:266
ULONG UDFLocateLbaInExtent(IN PVCB Vcb, IN PEXTENT_MAP Extent, IN lba_t lba)
Definition: extent.cpp:116
OSSTATUS UDFWriteExtent(IN PVCB Vcb, IN PEXTENT_INFO ExtInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, IN int8 *Buffer, OUT PSIZE_T WrittenBytes)
Definition: extent.cpp:3186
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define NOTHING
Definition: input_list.c:10
#define d
Definition: ke_i.h:81
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define MyFreePool__(addr)
Definition: mem_tools.h:152
ULONG MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen)
Definition: mem_tools.h:230
VOID UDFPreClrModified(IN PVCB Vcb)
Definition: misc_common.cpp:18
VOID UDFClrModified(IN PVCB Vcb)
Definition: misc_common.cpp:26
static struct proto Ext[]
Definition: mkg3states.c:87
#define ASSERT(a)
Definition: mode.c:44
#define __fastcall
Definition: sync.c:38
#define min(a, b)
Definition: monoChain.cc:55
void __fastcall UDFGetDstring(IN OUT PUNICODE_STRING UName, IN dstring *Dest, IN uint32 Length)
Definition: mount.cpp:783
OSSTATUS UDFUpdateXSpaceBitmaps(IN PVCB Vcb, IN uint32 PartNum, IN PPARTITION_HEADER_DESC phd)
Definition: mount.cpp:186
OSSTATUS UDFUpdateLogicalVol(IN PVCB Vcb, IN UDF_VDS_RECORD Lba, IN PUNICODE_STRING VolIdent)
Definition: mount.cpp:598
OSSTATUS UDFIsCachedBadSequence(IN PVCB Vcb, IN uint32 Lba)
Definition: mount.cpp:2569
OSSTATUS UDFLoadUnallocatedSpaceDesc(IN PVCB Vcb, int8 *Buf)
Definition: mount.cpp:2346
OSSTATUS UDFVerifyPartDesc(PVCB Vcb, int8 *Buf)
Definition: mount.cpp:2126
OSSTATUS UDFLoadSparingTable(IN PVCB Vcb, IN PSPARABLE_PARTITION_MAP PartMap)
Definition: mount.cpp:2783
#define CUR_IDENT_SZ
OSSTATUS UDFLoadPartition(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb, OUT lb_addr *fileset)
Definition: mount.cpp:2607
OSSTATUS UDFProcessSequence(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb, IN uint32 block, IN uint32 lastblock, OUT lb_addr *fileset)
Definition: mount.cpp:2360
OSSTATUS UDFUpdateVolIdent(IN PVCB Vcb, IN UDF_VDS_RECORD Lba, IN PUNICODE_STRING VolIdent)
Definition: mount.cpp:801
OSSTATUS UDFVerifyFreeSpaceBitmap(IN PVCB Vcb, IN uint32 PartNdx, IN PPARTITION_HEADER_DESC phd, IN uint32 Lba)
Definition: mount.cpp:1821
OSSTATUS UDFUpdatePartDesc(PVCB Vcb, int8 *Buf)
Definition: mount.cpp:299
OSSTATUS UDFUpdateVDS(IN PVCB Vcb, IN uint32 block, IN uint32 lastblock, IN uint32 flags)
Definition: mount.cpp:673
OSSTATUS UDFUpdateLogicalVolInt(PVCB Vcb, BOOLEAN Close)
Definition: mount.cpp:361
OSSTATUS UDFUpdateSparingTable(IN PVCB Vcb)
Definition: mount.cpp:462
OSSTATUS UDFPrepareXSpaceBitmap(IN PVCB Vcb, IN OUT PSHORT_AD XSpaceBitmap, IN OUT PEXTENT_INFO XSBMExtInfo, IN OUT int8 **XSBM, IN OUT uint32 *XSl)
Definition: mount.cpp:52
VOID UDFRememberBadSequence(IN PVCB Vcb, IN uint32 Lba, IN OSSTATUS RC)
Definition: mount.cpp:2587
lba_t UDFFindAnchor(PVCB Vcb)
Definition: mount.cpp:1011
OSSTATUS UDFFindLastFileSet(IN PVCB Vcb, IN lb_addr *Addr, IN OUT PFILE_SET_DESC FileSetDesc)
Definition: mount.cpp:2739
OSSTATUS UDFGetDiskInfoAndVerify(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: mount.cpp:2983
OSSTATUS UDFVerifySequence(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb, IN uint32 block, IN uint32 lastblock, OUT lb_addr *fileset)
Definition: mount.cpp:2461
BOOLEAN UDFCheckZeroBuf(IN int8 *Buf, IN uint32 Length)
Definition: mount.cpp:2936
OSSTATUS UDFLoadLogicalVolInt(PDEVICE_OBJECT DeviceObject, PVCB Vcb, extent_ad loc)
Definition: mount.cpp:1239
uint32 UDFFindVRS(PVCB Vcb)
Definition: mount.cpp:1108
OSSTATUS UDFVerifyXSpaceBitmap(IN PVCB Vcb, IN uint32 PartNum, IN PSHORT_AD bm, IN ULONG bm_type)
Definition: mount.cpp:1667
OSSTATUS UDFLoadBogusLogicalVol(PDEVICE_OBJECT DeviceObject, PVCB Vcb, int8 *Buf, lb_addr *fileset)
Definition: mount.cpp:1502
OSSTATUS __fastcall UDFSetDstring(IN PUNICODE_STRING UName, IN dstring *Dest, IN uint32 Length)
Definition: mount.cpp:757
OSSTATUS UDFLoadImpUseVolDesc(IN PVCB Vcb, int8 *Buf)
Definition: mount.cpp:2329
OSSTATUS UDFUmount__(IN PVCB Vcb)
Definition: mount.cpp:921
#define XCHG_DD(a, b)
Definition: mount.cpp:25
void UDFLoadFileset(IN PVCB Vcb, IN PFILE_SET_DESC fset, OUT lb_addr *root, OUT lb_addr *sysstream)
Definition: mount.cpp:2539
OSSTATUS UDFReadVDS(IN PVCB Vcb, IN uint32 block, IN uint32 lastblock, IN PUDF_VDS_RECORD vds, IN int8 *Buf)
Definition: mount.cpp:2239
OSSTATUS UDFAddXSpaceBitmap(IN PVCB Vcb, IN uint32 PartNum, IN PSHORT_AD bm, IN ULONG bm_type)
Definition: mount.cpp:1569
OSSTATUS UDFUpdateNonAllocated(IN PVCB Vcb)
Definition: mount.cpp:857
void UDFLoadPVolDesc(PVCB Vcb, int8 *Buf)
Definition: mount.cpp:1194
OSSTATUS UDFLoadLogicalVol(PDEVICE_OBJECT DeviceObject, PVCB Vcb, int8 *Buf, lb_addr *fileset)
Definition: mount.cpp:1374
OSSTATUS UDFLoadPartDesc(PVCB Vcb, int8 *Buf)
Definition: mount.cpp:2023
OSSTATUS UDFBuildFreeSpaceBitmap(IN PVCB Vcb, IN uint32 PartNdx, IN PPARTITION_HEADER_DESC phd, IN uint32 Lba)
Definition: mount.cpp:1910
int k
Definition: mpi.c:3369
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define UDF_TYPE1_MAP15
Definition: osta_misc.h:92
#define SPARING_LOC_CORRUPTED
Definition: osta_misc.h:196
PSPARING_ENTRY PSPARING_MAP
Definition: osta_misc.h:202
#define UDF_ID_DEVELOPER
Definition: osta_misc.h:20
#define SPARING_LOC_AVAILABLE
Definition: osta_misc.h:195
#define UDF_EXTENT_LENGTH_MASK
Definition: osta_misc.h:148
#define UDF_VIRTUAL_MAP20
Definition: osta_misc.h:94
#define UDF_ID_SPARABLE
Definition: osta_misc.h:276
SparingEntry SPARING_ENTRY
Definition: osta_misc.h:198
struct _SPARING_TABLE SPARING_TABLE
struct _SPARING_TABLE * PSPARING_TABLE
#define UDF_ID_METADATA
Definition: osta_misc.h:277
#define UDF_METADATA_MAP25
Definition: osta_misc.h:96
#define TID_ADAPTEC_LOGICAL_VOL_DESC
Definition: osta_misc.h:349
#define UDF_ID_VIRTUAL
Definition: osta_misc.h:275
#define UDF_SPARABLE_MAP15
Definition: osta_misc.h:95
struct _SPARABLE_PARTITION_MAP * PSPARABLE_PARTITION_MAP
#define UDF_VIRTUAL_MAP15
Definition: osta_misc.h:93
struct _SparingEntry SparingEntry
unsigned short USHORT
Definition: pedump.c:61
#define Vcb
Definition: cdprocs.h:1415
OSSTATUS UDFWriteSectors(IN PVCB Vcb, IN BOOLEAN Translate, IN uint32 Lba, IN uint32 BCount, IN BOOLEAN Direct, IN int8 *Buffer, OUT PSIZE_T WrittenBytes)
Definition: phys_lib.cpp:4012
OSSTATUS UDFReadData(IN PVCB Vcb, IN BOOLEAN Translate, IN LONGLONG Offset, IN ULONG Length, IN BOOLEAN Direct, OUT PCHAR Buffer, OUT PSIZE_T ReadBytes)
#define UDFReadSectors(Vcb, Translate, Lba, BCount, Direct, Buffer, ReadBytes)
Definition: phys_lib.h:126
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:48
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define equal(x, y)
Definition: reader.cc:56
VOID UDFVFlush(IN PVCB Vcb)
Definition: remap.cpp:742
static calc_node_t * pop(void)
Definition: rpn_ieee.c:90
static void push(calc_node_t *op)
Definition: rpn_ieee.c:113
@ Close
Definition: sacdrv.h:268
#define STATUS_SUCCESS
Definition: shellext.h:65
extent_ad reserveVolDescSeqExt
Definition: ecma_167.h:219
extent_ad mainVolDescSeqExt
Definition: ecma_167.h:218
uint8 ident[23]
Definition: ecma_167.h:61
uint8 identSuffix[8]
Definition: ecma_167.h:62
uint32 volDescSeqNum
Definition: ecma_167.h:338
uint8 partitionMapType
Definition: ecma_167.h:294
uint8 partitionMapLength
Definition: ecma_167.h:295
uint32 volDescSeqNum
Definition: ecma_167.h:236
uint8 impUse[460]
Definition: ecma_167.h:238
uint32 numPartitionMaps
Definition: ecma_167.h:285
uint32 mapTableLength
Definition: ecma_167.h:284
extent_ad integritySeqExt
Definition: ecma_167.h:288
uint8 logicalVolContentsUse[16]
Definition: ecma_167.h:283
EntityID domainIdent
Definition: ecma_167.h:282
uint32 logicalBlockSize
Definition: ecma_167.h:281
dstring logicalVolIdent[128]
Definition: ecma_167.h:280
uint32 volDescSeqNum
Definition: ecma_167.h:278
uint8 logicalVolContentsUse[32]
Definition: ecma_167.h:348
uint16 maxInterchangeLvl
Definition: ecma_167.h:195
uint32 charSetList
Definition: ecma_167.h:196
dstring volSetIdent[128]
Definition: ecma_167.h:198
timestamp recordingDateAndTime
Definition: ecma_167.h:204
uint16 volSeqNum
Definition: ecma_167.h:192
uint32 maxCharSetList
Definition: ecma_167.h:197
uint32 primaryVolDescNum
Definition: ecma_167.h:190
uint16 flags
Definition: ecma_167.h:208
uint16 interchangeLvl
Definition: ecma_167.h:194
uint32 volDescSeqNum
Definition: ecma_167.h:189
dstring volIdent[32]
Definition: ecma_167.h:191
uint16 maxVolSeqNum
Definition: ecma_167.h:193
uint16 currentRev
Definition: osta_misc.h:226
EntityID partIdent
Definition: osta_misc.h:53
uint16 partitionNum
Definition: osta_misc.h:55
uint16 volSeqNum
Definition: osta_misc.h:54
uint32 volDescSeqNum
Definition: ecma_167.h:226
extent_ad nextVolDescSeqExt
Definition: ecma_167.h:227
uint8 structType
Definition: ecma_167.h:73
uint8 stdIdent[STD_ID_LEN]
Definition: ecma_167.h:74
uint32 extLength
Definition: ecma_167.h:128
uint32 extLocation
Definition: ecma_167.h:129
PEXTENT_MAP Mapping
Definition: udf_rel.h:66
int64 Length
Definition: udf_rel.h:67
BOOLEAN Modified
Definition: udf_rel.h:68
uint32 Offset
Definition: udf_rel.h:65
short_ad unallocatedSpaceBitmap
Definition: ecma_167.h:416
short_ad partitionIntegrityTable
Definition: ecma_167.h:417
short_ad unallocatedSpaceTable
Definition: ecma_167.h:415
short_ad freedSpaceTable
Definition: ecma_167.h:418
short_ad freedSpaceBitmap
Definition: ecma_167.h:419
uint32 extLength
Definition: ecma_167.h:407
uint32 extPosition
Definition: ecma_167.h:408
uint32 mappedLocation
Definition: osta_misc.h:192
uint32 origLocation
Definition: osta_misc.h:191
uint32 block
Definition: udf_rel.h:108
Definition: cdstruc.h:498
uint16 partitionReferenceNum
Definition: ecma_167.h:363
uint32 logicalBlockNum
Definition: ecma_167.h:362
lb_addr extLocation
Definition: ecma_167.h:375
Definition: ps.c:97
Definition: ecma_167.h:138
uint16 tagSerialNum
Definition: ecma_167.h:143
uint32 tagLocation
Definition: ecma_167.h:146
uint16 descCRCLength
Definition: ecma_167.h:145
uint16 tagIdent
Definition: ecma_167.h:139
#define max(a, b)
Definition: svc.c:63
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx shrl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm0 paddd mm4 psrad mm0 psrad mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx andl ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm0 psrad mm0 packssdw mm0 movd eax movw edi esi edx edi
Definition: synth_sse3d.h:185
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl eax
Definition: synth_sse3d.h:85
#define BS
Definition: telnetd.h:22
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define MAX_SPARING_TABLE_LOCATIONS
Definition: udf_common.h:36
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define MAX_ANCHOR_LOCATIONS
Definition: udf_common.h:35
#define UDF_VCB_ASSUME_ALL_USED
Definition: udf_common.h:474
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
#define UDF_VCB_IC_MRW_ADDR_PROBLEM
Definition: udf_common.h:510
#define UDF_VCB_IC_W2K_COMPAT_VLABEL
Definition: udf_common.h:517
void UDFSetUpTag(IN PVCB Vcb, IN tag *Tag, IN uint16 DataLen, IN uint32 TagLoc)
Definition: udf_info.cpp:936
void __fastcall UDFCompressUnicode(IN PUNICODE_STRING UName, IN OUT uint8 **_CS0, IN OUT PSIZE_T Length)
Definition: udf_info.cpp:240
OSSTATUS UDFFlushFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN ULONG FlushFlags)
Definition: udf_info.cpp:4119
void UDFReadEntityID_Domain(PVCB Vcb, EntityID *eID)
Definition: udf_info.cpp:1559
OSSTATUS UDFReadTagged(PVCB Vcb, int8 *Buf, uint32 Block, uint32 Location, uint16 *Ident)
Definition: udf_info.cpp:4586
OSSTATUS UDFLoadVAT(IN PVCB Vcb, IN uint32 PartNdx)
Definition: udf_info.cpp:3602
OSSTATUS UDFRecordVAT(IN PVCB Vcb)
Definition: udf_info.cpp:5036
void __fastcall UDFDecompressUnicode(IN OUT PUNICODE_STRING UName, IN uint8 *CS0, IN SIZE_T Length, OUT uint16 *valueCRC)
Definition: udf_info.cpp:170
#define lba
#define UDFSetEntityID_imp(eID, Str)
Definition: udf_info.h:598
#define UDF_ZSPACE_BM
Definition: udf_info.h:446
#define AS_USED
Definition: udf_info.h:327
#define UDFGetUsedBit(arr, bit)
Definition: udf_info.h:1198
#define UDFAllocFreeExtent(v, l, ss, sl, e, af)
Definition: udf_info.h:347
#define UDFClrZeroBit(arr, bit)
Definition: udf_info.h:1209
#define UDFGetPartNumByPartNdx(Vcb, pi)
Definition: udf_info.h:1028
#define UDFExtentToMapping(e)
Definition: udf_info.h:181
#define UDF_PREALLOC_CLASS_DIR
Definition: udf_info.h:356
#define UDFSetFreeBit(arr, bit)
Definition: udf_info.h:1201
#define UDFSetUsedBit(arr, bit)
Definition: udf_info.h:1200
#define UDFRegisterFsStructure(Vcb, Lba, Length)
Definition: udf_info.h:1250
#define UDFGetZeroBit(arr, bit)
Definition: udf_info.h:1207
#define UDFSetFreeBitOwner(Vcb, i)
Definition: udf_info.h:1235
#define UDF_FSPACE_BM
Definition: udf_info.h:445
#define UDF_PREALLOC_CLASS_FE
Definition: udf_info.h:355
#define UDFGetLVIDiUse(Vcb)
Definition: udf_info.h:884
#define UDFSetZeroBit(arr, bit)
Definition: udf_info.h:1208
#define UDFGetFreeBit(arr, bit)
Definition: udf_info.h:1199
#define UDFGetBadBit(arr, bit)
Definition: udf_info.h:1205
#define UDFSetUsedBits(arr, bit, bc)
Definition: udf_info.h:1202
#define UDFMarkSpaceAsXXX(Vcb, FileInfo, Map, asXXX)
Definition: udf_info.h:322
#define VDS_POS_LENGTH
Definition: udf_rel.h:105
#define VDS_POS_UNALLOC_SPACE_DESC
Definition: udf_rel.h:98
struct _UDFPartMap * PUDFPartMap
#define VDS_POS_PARTITION_DESC
Definition: udf_rel.h:100
#define UDF_LVID_TTL
Definition: udf_rel.h:517
#define VRS_NSR02_FOUND
Definition: udf_rel.h:112
#define VDS_POS_RECURSION_COUNTER
Definition: udf_rel.h:104
#define UDF_MAX_LVID_CHAIN_LENGTH
Definition: udf_rel.h:516
#define VDS_POS_TERMINATING_DESC
Definition: udf_rel.h:103
#define RELOC_MAP_GRAN
Definition: udf_rel.h:119
#define VRS_NSR03_FOUND
Definition: udf_rel.h:113
#define VDS_POS_LOGICAL_VOL_DESC
Definition: udf_rel.h:99
#define VDS_POS_VOL_DESC_PTR
Definition: udf_rel.h:102
#define VDS_POS_PRIMARY_VOL_DESC
Definition: udf_rel.h:97
#define UDF_MAX_WRITE_REVISION
Definition: udf_rel.h:514
#define VRS_ISO9660_FOUND
Definition: udf_rel.h:114
#define LBA_OUT_OF_EXTENT
Definition: udf_rel.h:426
#define UDF_MAX_READ_REVISION
Definition: udf_rel.h:513
#define VDS_POS_IMP_USE_VOL_DESC
Definition: udf_rel.h:101
#define EXTENT_FLAG_ALLOC_SEQUENTIAL
Definition: udf_rel.h:77
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
#define STATUS_NONEXISTENT_SECTOR
Definition: udferr_usr.h:143
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define STATUS_INVALID_VOLUME_LABEL
Definition: udferr_usr.h:156
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define UDF_CHECK_BITMAP_RESOURCE(Vcb)
Definition: udffs.h:262
#define UDFPrint(Args)
Definition: udffs.h:223
#define UDF_PART_DAMAGED_RW
Definition: udfpubl.h:120
#define UDF_USER_FS_FLAGS_MEDIA_DEFECT_RO
Definition: udfpubl.h:114
#define UDF_USER_FS_FLAGS_NEW_FS_RO
Definition: udfpubl.h:116
#define UDF_USER_FS_FLAGS_PART_RO
Definition: udfpubl.h:115
#define UDF_PART_DAMAGED_NO
Definition: udfpubl.h:122
#define UDF_PART_DAMAGED_RO
Definition: udfpubl.h:121
VOID WCacheFlushAll__(IN PW_CACHE Cache, IN PVOID Context)
ULONG WCacheGetWriteBlockCount__(IN PW_CACHE Cache)
OSSTATUS WCacheFlushBlocks__(IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba, IN ULONG BCount)
VOID WCachePurgeAll__(IN PW_CACHE Cache, IN PVOID Context)
OSSTATUS WCacheSetMode__(IN PW_CACHE Cache, IN ULONG Mode)
#define WCACHE_MODE_R
Definition: wcache_lib.h:126
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
static unsigned int block
Definition: xmlmemory.c:101