ReactOS  0.4.14-dev-52-g6116262
mount.cpp
Go to the documentation of this file.
1 // 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  */
185 OSSTATUS
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  */
298 OSSTATUS
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  *//*
340 OSSTATUS
341 UDFUpdateUSpaceDesc(
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  */
360 OSSTATUS
362  PVCB Vcb,
363  BOOLEAN Close
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;
376  BOOLEAN equal = FALSE;
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,
443  sizeof(LogicalVolIntegrityDesc) +
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  */
461 OSSTATUS
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);
494 swp_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  */
597 OSSTATUS
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))
606  dstring CS0[CUR_IDENT_SZ];
607  uint16 ident;
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;
641  if(ident != TID_LOGICAL_VOL_DESC) {
643  goto Err_SetVI;
644  }
645 
646  if(RtlCompareMemory(lvd->logicalVolIdent, CS0, CUR_IDENT_SZ) == CUR_IDENT_SZ) {
647  // no changes
648  UDFPrint(("UDF: equal VolIds\n"));
650  goto Err_SetVI;
651  }
652  RtlCopyMemory(lvd->logicalVolIdent, CS0, CUR_IDENT_SZ);
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 
659 Err_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  */
672 OSSTATUS
674  IN PVCB Vcb,
675  IN uint32 block,
676  IN uint32 lastblock,
677  IN uint32 flags
678  )
679 {
681  int8* Buf = (int8*)DbgAllocatePool(NonPagedPool,Vcb->LBlockSize);
683  uint32 i,j;
684  uint16 ident;
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
723  if(i == VDS_POS_PARTITION_DESC) {
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  }
732  UDFUpdatePartDesc(Vcb,Buf);
733  for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++) {
734  UDFReadTagged(Vcb,Buf2, j, j, &ident);
735  if (ident == TID_PARTITION_DESC)
736  UDFUpdatePartDesc(Vcb,Buf2);
737  }
738  DbgFreePool(Buf2);
739 // continue;
740  } else
741  // update Vol Ident Desc
742  if(i == VDS_POS_LOGICAL_VOL_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 
755 OSSTATUS
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 
781 void
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  */
800 OSSTATUS
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))
808  PrimaryVolDesc* pvoldesc = (PrimaryVolDesc*)MyAllocatePool__(NonPagedPool, max(Vcb->BlockSize, sizeof(PrimaryVolDesc)) );
810  dstring CS0[CUR_IDENT_SZ];
811  uint16 ident;
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;
832  if(ident != TID_PRIMARY_VOL_DESC) {
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);
848 Err_SetVI:
849  MyFreePool__(pvoldesc);
850  return status;
851 
852 #undef CUR_IDENT_SZ
853 } // end UDFUpdateVolIdent()
854 #endif //UDF_READ_ONLY_BUILD
855 
856 OSSTATUS
858  IN PVCB Vcb
859  )
860 {
861  uint32 PartNum;
862  uint32 i;
863  uint32 plen, pstart, pend;
864  int8* bad_bm;
865  EXTENT_AD Ext;
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
894  if(UDFLocateLbaInExtent(Vcb, DataLoc->Mapping, i) != LBA_OUT_OF_EXTENT) {
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  */
920 OSSTATUS
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 */
1010 lba_t
1012  PVCB Vcb // Volume control block
1013  )
1014 {
1015 // OSSTATUS RC = STATUS_SUCCESS;
1016 
1017  uint16 ident;
1018  uint32 i;
1019  uint32 LastBlock;
1020  OSSTATUS status;
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]));
1053  if(!OS_SUCCESS(status = UDFReadTagged(Vcb,Buf,
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 {
1074 MRW_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"));
1089  Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_READ_ONLY;
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  */
1107 uint32
1109  PVCB Vcb
1110  )
1111 {
1112  VolStructDesc *vsd = NULL;
1113  uint32 offset;
1114  uint32 retStat = 0;
1115  uint32 BeginOffset = Vcb->FirstLBA;
1116  OSSTATUS RC;
1117  int8* buffer = (int8*)MyAllocatePool__(NonPagedPool,Vcb->BlockSize);
1118  SIZE_T ReadBytes;
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  */
1193 void
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
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  */
1238 OSSTATUS
1241  PVCB Vcb,
1242  extent_ad loc
1243  )
1244 {
1245  OSSTATUS RC = STATUS_SUCCESS;
1246  uint32 len;
1247  SIZE_T _ReadBytes;
1248  int8* Buf = NULL;
1249  uint16 ident;
1250  LogicalVolIntegrityDescImpUse* LVID_iUse;
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)) {
1270 exit_with_err:
1271  UDFPrint(("UDF: Reading LVID @%x (%x) failed.\n", loc.extLocation, loc.extLength));
1272  switch(Vcb->PartitialDamagedVolumeAction) {
1273  case UDF_PART_DAMAGED_RO:
1274  UDFPrint(("UDF: Switch to r/o mode.\n"));
1275  Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_READ_ONLY;
1276  Vcb->UserFSFlags |= UDF_USER_FS_FLAGS_MEDIA_DEFECT_RO;
1277  RC = STATUS_SUCCESS;
1278  break;
1279  case UDF_PART_DAMAGED_NO:
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;
1284  case UDF_PART_DAMAGED_RW:
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));
1355  Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_READ_ONLY;
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  */
1373 OSSTATUS
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));
1430  if(type == PARTITION_MAP_TYPE_1)
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;
1466  status = UDFLoadSparingTable(Vcb, spm);
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 
1501 OSSTATUS
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  */
1568 OSSTATUS
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;
1580  OSSTATUS status;
1581  uint16 Ident;
1582  uint32 flags;
1583  SIZE_T Length;
1584  SIZE_T ReadBytes;
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)) ) {
1603 err_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  */
1666 OSSTATUS
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;
1679  OSSTATUS status;
1680  uint16 Ident;
1681  uint32 flags;
1682  uint32 Length;
1683  SIZE_T ReadBytes;
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)) ) {
1701 err_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
1765 UDFDelXSpaceBitmap(
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  */
1820 OSSTATUS
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 {
1828  OSSTATUS status;
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;
1889  Extent = UDFMergeMappings(Extent, (PEXTENT_MAP)(AllocDesc+sizeof(UNALLOC_SPACE_DESC)) );
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  */
1909 OSSTATUS
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 {
1917  OSSTATUS status;
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
1934 free_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;
2004  Extent = UDFMergeMappings(Extent, (PEXTENT_MAP)(AllocDesc+sizeof(UNALLOC_SPACE_DESC)) );
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  */
2022 OSSTATUS
2024  PVCB Vcb,
2025  int8* Buf
2026  )
2027 {
2028  PartitionDesc *p = (PartitionDesc *)Buf;
2029  uint32 i;
2030  OSSTATUS RC;
2031  BOOLEAN Found = FALSE;
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"));
2058  Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_READ_ONLY;
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  */
2125 OSSTATUS
2127  PVCB Vcb,
2128  int8* Buf
2129  )
2130 {
2131  PartitionDesc *p = (PartitionDesc *)Buf;
2132  uint32 i;
2133  OSSTATUS RC;
2134  BOOLEAN Found = FALSE;
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  */
2238 OSSTATUS
2240  IN PVCB Vcb,
2241  IN uint32 block,
2242  IN uint32 lastblock,
2243  IN PUDF_VDS_RECORD vds,
2244  IN int8* Buf
2245  )
2246 {
2247  OSSTATUS status;
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  {
2257  status = UDFReadTagged(Vcb, Buf, block, block, &ident);
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
2269  if(vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum)
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  {
2279  vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
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
2294  if(vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum)
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
2301  if(!vds[VDS_POS_PARTITION_DESC].block)
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
2306  if(vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum)
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
2313  if(vdsn >= vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum)
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 
2328 OSSTATUS
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 
2345 OSSTATUS
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 */
2359 OSSTATUS
2362  IN PVCB Vcb,
2363  IN uint32 block,
2364  IN uint32 lastblock,
2365  OUT lb_addr *fileset
2366  )
2367 {
2368  OSSTATUS RC = STATUS_SUCCESS;
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 
2392  if(i == VDS_POS_PRIMARY_VOL_DESC) {
2393  UDFLoadPVolDesc(Vcb,Buf);
2394  if(!Vcb->PVolDescAddr.block) {
2395  Vcb->PVolDescAddr = vds[i];
2396  } else {
2397  Vcb->PVolDescAddr2 = vds[i];
2398  }
2399  } else
2400  if(i == VDS_POS_LOGICAL_VOL_DESC) {
2401  RC = UDFLoadLogicalVol(DeviceObject,Vcb, Buf, fileset);
2402  if(!OS_SUCCESS(RC)) try_return(RC);
2403  } else
2404 
2405  if(i == VDS_POS_IMP_USE_VOL_DESC) {
2406  UDFLoadImpUseVolDesc(Vcb, Buf);
2407  } else
2408  if(i == VDS_POS_UNALLOC_SPACE_DESC) {
2410  } else
2411 
2412  if(i == VDS_POS_PARTITION_DESC)
2413  {
2414  Buf2 = (int8*)MyAllocatePool__(NonPagedPool,Vcb->BlockSize);
2415  if(!Buf2) try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
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 {
2440  if(i == VDS_POS_LOGICAL_VOL_DESC) {
2441  RC = UDFLoadBogusLogicalVol(DeviceObject,Vcb, Buf, fileset);
2442  if(!OS_SUCCESS(RC)) try_return(RC);
2443  }
2444  }
2445  }
2446 
2447 try_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 */
2460 OSSTATUS
2463  IN PVCB Vcb,
2464  IN uint32 block,
2465  IN uint32 lastblock,
2466  OUT lb_addr *fileset
2467  )
2468 {
2469  OSSTATUS RC = STATUS_SUCCESS;
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);
2501  if(!Buf2) try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
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  }
2525 try_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  */
2538 void
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 
2568 OSSTATUS
2570  IN PVCB Vcb,
2571  IN uint32 Lba
2572  )
2573 {
2574  ULONG j;
2575  OSSTATUS RC = STATUS_SUCCESS;
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 
2586 VOID
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  */
2606 OSSTATUS
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) {
2696  case UDF_PART_DAMAGED_RO:
2697  UDFPrint(("UDF: Switch to r/o mode.\n"));
2698  Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_READ_ONLY;
2699  break;
2700  case UDF_PART_DAMAGED_NO:
2701  UDFPrint(("UDF: Switch to raw mount mode, return UNRECOGNIZED_VOLUME.\n"));
2702  Vcb->VCBFlags |= UDF_VCB_FLAGS_RAW_DISK;
2703  RC = STATUS_WRONG_VOLUME;
2704  break;
2705  case UDF_PART_DAMAGED_RW:
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"));
2719  Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_READ_ONLY;
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  */
2738 OSSTATUS
2740  IN PVCB Vcb,
2741  IN lb_addr *Addr, // Addr for the 1st FileSet
2742  IN OUT PFILE_SET_DESC FileSetDesc
2743  )
2744 {
2745  OSSTATUS status;
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  */
2782 OSSTATUS
2784  IN PVCB Vcb,
2785  IN PSPARABLE_PARTITION_MAP PartMap
2786  )
2787 {
2788  PSPARING_MAP RelocMap;
2789  PSPARING_MAP NewRelocMap;
2790  OSSTATUS status;
2791  uint32 i=0, BC, BC2;
2792  PSPARING_TABLE SparTable;
2793  uint32 TabSize, NewSize;
2794  SIZE_T ReadBytes;
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  */
2935 BOOLEAN
2937  IN int8* Buf,
2938  IN uint32 Length
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 
2958 not_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 */
2982 OSSTATUS
2984  IN PDEVICE_OBJECT DeviceObject, // the target device object
2985  IN PVCB Vcb // Volume control block from this DevObj
2986  )
2987 {
2989  uint32 NSRDesc;
2990  lb_addr fileset;
2991  PFILE_SET_DESC FileSetDesc = NULL;
2992 
2993  int8* Buf = NULL;
2994  SIZE_T ReadBytes;
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"));
3003 check_NSR:
3004  NSRDesc = UDFFindVRS(Vcb);
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 
3054 try_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 long long uint64
Definition: platform.h:18
static unsigned int block
Definition: xmlmemory.c:118
OSSTATUS UDFAddXSpaceBitmap(IN PVCB Vcb, IN uint32 PartNum, IN PSHORT_AD bm, IN ULONG bm_type)
Definition: mount.cpp:1569
uint16 tagIdent
Definition: ecma_167.h:139
uint32 volDescSeqNum
Definition: ecma_167.h:236
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define DbgAllocatePool
Definition: env_spec_w32.h:332
#define VDS_POS_PRIMARY_VOL_DESC
Definition: udf_rel.h:97
OSSTATUS UDFUpdateXSpaceBitmaps(IN PVCB Vcb, IN uint32 PartNum, IN PPARTITION_HEADER_DESC phd)
Definition: mount.cpp:186
short_ad unallocatedSpaceBitmap
Definition: ecma_167.h:416
OSSTATUS UDFUpdateSparingTable(IN PVCB Vcb)
Definition: mount.cpp:462
#define IN
Definition: typedefs.h:38
struct _FILE_SET_DESC * PFILE_SET_DESC
#define max(a, b)
Definition: svc.c:63
uint32 extLength
Definition: ecma_167.h:407
uint8 structType
Definition: ecma_167.h:73
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define TID_TERMINAL_ENTRY
Definition: ecma_167.h:169
SparingEntry SPARING_ENTRY
Definition: osta_misc.h:198
#define TID_UNALLOC_SPACE_DESC
Definition: ecma_167.h:160
EntityID partIdent
Definition: osta_misc.h:53
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define EXTENT_RECORDED_ALLOCATED
Definition: ecma_167.h:367
#define UDF_MAX_WRITE_REVISION
Definition: udf_rel.h:514
void __fastcall UDFPackMapping(IN PVCB Vcb, IN PEXTENT_INFO ExtInfo)
Definition: extent.cpp:2747
static void xor(unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count)
Definition: crypt_des.c:251
uint8 partitionMapType
Definition: ecma_167.h:294
BOOLEAN Modified
Definition: udf_rel.h:68
#define KdDump(a, b)
Definition: env_spec_w32.h:312
uint32 numPartitionMaps
Definition: ecma_167.h:285
uint16 maxInterchangeLvl
Definition: ecma_167.h:195
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
struct x86_inst instr
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define VDS_POS_IMP_USE_VOL_DESC
Definition: udf_rel.h:101
#define PARTITION_ACCESS_WO
Definition: ecma_167.h:270
extent_ad mainVolDescSeqExt
Definition: ecma_167.h:218
#define __fastcall
Definition: sync.c:41
uint32 origLocation
Definition: osta_misc.h:191
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
OSSTATUS UDFLoadUnallocatedSpaceDesc(IN PVCB Vcb, int8 *Buf)
Definition: mount.cpp:2346
OSSTATUS UDFLoadLogicalVolInt(PDEVICE_OBJECT DeviceObject, PVCB Vcb, extent_ad loc)
Definition: mount.cpp:1239
#define INTEGRITY_TYPE_CLOSE
Definition: ecma_167.h:358
#define VDS_POS_PARTITION_DESC
Definition: udf_rel.h:100
#define UDFSetEntityID_imp(eID, Str)
Definition: udf_info.h:598
unsigned int uint32
Definition: types.h:32
#define TID_ADAPTEC_LOGICAL_VOL_DESC
Definition: osta_misc.h:349
#define UDFSetFreeBit(arr, bit)
Definition: udf_info.h:1201
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
ULONG MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen)
Definition: mem_tools.h:224
uint32 mapTableLength
Definition: ecma_167.h:284
#define UDFRegisterFsStructure(Vcb, Lba, Length)
Definition: udf_info.h:1250
GLintptr offset
Definition: glext.h:5920
void UDFSetUpTag(IN PVCB Vcb, IN tag *Tag, IN uint16 DataLen, IN uint32 TagLoc)
Definition: udf_info.cpp:936
OSSTATUS UDFUpdateVDS(IN PVCB Vcb, IN uint32 block, IN uint32 lastblock, IN uint32 flags)
Definition: mount.cpp:673
#define equal(x, y)
Definition: reader.cc:56
OSSTATUS __fastcall UDFSetDstring(IN PUNICODE_STRING UName, IN dstring *Dest, IN uint32 Length)
Definition: mount.cpp:757
extent_ad integritySeqExt
Definition: ecma_167.h:288
GLdouble n
Definition: glext.h:7729
#define UDF_FSPACE_BM
Definition: udf_info.h:445
OSSTATUS UDFLoadLogicalVol(PDEVICE_OBJECT DeviceObject, PVCB Vcb, int8 *Buf, lb_addr *fileset)
Definition: mount.cpp:1374
#define TID_TERMINATING_DESC
Definition: ecma_167.h:161
uint32 extLocation
Definition: ecma_167.h:129
OSSTATUS UDFLoadImpUseVolDesc(IN PVCB Vcb, int8 *Buf)
Definition: mount.cpp:2329
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
Definition: ecma_167.h:138
Definition: cdstruc.h:504
GLuint buffer
Definition: glext.h:5915
uint32 tagLocation
Definition: ecma_167.h:146
#define MAX_ANCHOR_LOCATIONS
Definition: udf_common.h:35
lb_addr extLocation
Definition: ecma_167.h:375
OSSTATUS UDFReadData(IN PVCB Vcb, IN BOOLEAN Translate, IN LONGLONG Offset, IN ULONG Length, IN BOOLEAN Direct, OUT PCHAR Buffer, OUT PSIZE_T ReadBytes)
uint32 mappedLocation
Definition: osta_misc.h:192
#define STATUS_INVALID_VOLUME_LABEL
Definition: udferr_usr.h:156
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define UDF_PREALLOC_CLASS_FE
Definition: udf_info.h:355
short_ad freedSpaceBitmap
Definition: ecma_167.h:419
OSSTATUS UDFBuildFreeSpaceBitmap(IN PVCB Vcb, IN uint32 PartNdx, IN PPARTITION_HEADER_DESC phd, IN uint32 Lba)
Definition: mount.cpp:1910
OSSTATUS UDFGetDiskInfoAndVerify(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: mount.cpp:2983
int64 Length
Definition: udf_rel.h:67
static calc_node_t * pop(void)
Definition: rpn_ieee.c:90
struct _SPARABLE_PARTITION_MAP * PSPARABLE_PARTITION_MAP
#define lba
uint16 volSeqNum
Definition: osta_misc.h:54
OSSTATUS UDFVerifyPartDesc(PVCB Vcb, int8 *Buf)
Definition: mount.cpp:2126
#define STD_ID_NSR02
Definition: ecma_167.h:84
uint32 volDescSeqNum
Definition: ecma_167.h:338
const GLfloat * m
Definition: glext.h:10848
#define UDF_PART_DAMAGED_RO
Definition: udfpubl.h:121
#define UDF_ZSPACE_BM
Definition: udf_info.h:446
OSSTATUS UDFLoadPartition(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb, OUT lb_addr *fileset)
Definition: mount.cpp:2607
#define STATUS_NONEXISTENT_SECTOR
Definition: udferr_usr.h:143
struct _SPACE_BITMAP_DESC SPACE_BITMAP_DESC
#define UDF_VIRTUAL_MAP20
Definition: osta_misc.h:94
#define UDFGetLVIDiUse(Vcb)
Definition: udf_info.h:884
void UDFLoadPVolDesc(PVCB Vcb, int8 *Buf)
Definition: mount.cpp:1194
_SEH2_TRY
Definition: create.c:4250
uint16 interchangeLvl
Definition: ecma_167.h:194
VOID WCachePurgeAll__(IN PW_CACHE Cache, IN PVOID Context)
OSSTATUS UDFUpdateVolIdent(IN PVCB Vcb, IN UDF_VDS_RECORD Lba, IN PUNICODE_STRING VolIdent)
Definition: mount.cpp:801
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
PEXTENT_MAP Mapping
Definition: udf_rel.h:66
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
#define UDFSetFreeBitOwner(Vcb, i)
Definition: udf_info.h:1235
VOID WCacheFlushAll__(IN PW_CACHE Cache, IN PVOID Context)
OSSTATUS UDFLoadPartDesc(PVCB Vcb, int8 *Buf)
Definition: mount.cpp:2023
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define UDF_VCB_IC_W2K_COMPAT_VLABEL
Definition: udf_common.h:517
OSSTATUS UDFUpdateLogicalVolInt(PVCB Vcb, BOOLEAN Close)
Definition: mount.cpp:361
OSSTATUS UDFLoadBogusLogicalVol(PDEVICE_OBJECT DeviceObject, PVCB Vcb, int8 *Buf, lb_addr *fileset)
Definition: mount.cpp:1502
#define TID_EXTENDED_FILE_ENTRY
Definition: ecma_167.h:175
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
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
uint32 __fastcall UDFGetPartFreeSpace(IN PVCB Vcb, IN uint32 partNum)
Definition: alloc.cpp:1086
#define VDS_POS_LENGTH
Definition: udf_rel.h:105
#define UDF_ID_DEVELOPER
Definition: osta_misc.h:20
#define UDF_ID_SPARABLE
Definition: osta_misc.h:276
OSSTATUS UDFFlushAllCachedAllocations(IN PVCB Vcb, IN uint32 AllocClass)
Definition: extent.cpp:1508
extent_ad reserveVolDescSeqExt
Definition: ecma_167.h:219
struct _SPARING_TABLE * PSPARING_TABLE
#define UDF_USER_FS_FLAGS_MEDIA_DEFECT_RO
Definition: udfpubl.h:114
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
uint32 charSetList
Definition: ecma_167.h:196
#define UDF_METADATA_MAP25
Definition: osta_misc.h:96
uint16 currentRev
Definition: osta_misc.h:226
uint32 __fastcall UDFPartLbaToPhys(IN PVCB Vcb, IN lb_addr *Addr)
Definition: alloc.cpp:114
#define OSSTATUS
Definition: env_spec_w32.h:57
#define MAX_SPARING_TABLE_LOCATIONS
Definition: udf_common.h:36
uint16 volSeqNum
Definition: ecma_167.h:192
#define STD_ID_CD001
Definition: ecma_167.h:82
uint16 partitionNum
Definition: osta_misc.h:55
struct _ACPI_EFI_BOOT_SERVICES * BS
#define TID_PARTITION_DESC
Definition: ecma_167.h:158
#define PARTITION_MAP_TYPE_1
Definition: ecma_167.h:301
#define MAX_VDS_PARTS
Definition: ecma_167.h:231
#define UDF_PART_DAMAGED_RW
Definition: udfpubl.h:120
#define PARTITION_ACCESS_MAX_KNOWN
Definition: ecma_167.h:273
unsigned char BOOLEAN
uint32 maxCharSetList
Definition: ecma_167.h:197
PSPARING_ENTRY PSPARING_MAP
Definition: osta_misc.h:202
#define VRS_NSR03_FOUND
Definition: udf_rel.h:113
#define EXTENT_NOT_RECORDED_NOT_ALLOCATED
Definition: ecma_167.h:369
smooth NULL
Definition: ftsmooth.c:416
#define TID_PRIMARY_VOL_DESC
Definition: ecma_167.h:154
BOOLEAN UDFCheckZeroBuf(IN int8 *Buf, IN uint32 Length)
Definition: mount.cpp:2936
OSSTATUS UDFFlushFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN ULONG FlushFlags)
Definition: udf_info.cpp:4119
uint32 volDescSeqNum
Definition: ecma_167.h:226
#define UDF_USER_FS_FLAGS_PART_RO
Definition: udfpubl.h:115
uint32 volDescSeqNum
Definition: ecma_167.h:278
return Found
Definition: dirsup.c:1270
OSSTATUS UDFLoadSparingTable(IN PVCB Vcb, IN PSPARABLE_PARTITION_MAP PartMap)
Definition: mount.cpp:2783
int64 UDFGetExtentLength(IN PEXTENT_MAP Extent)
Definition: extent.cpp:142
uint32 __fastcall UDFPartStart(PVCB Vcb, uint32 PartNum)
Definition: alloc.cpp:222
#define STD_ID_NSR03
Definition: ecma_167.h:85
OSSTATUS UDFRecordVAT(IN PVCB Vcb)
Definition: udf_info.cpp:5036
#define TID_UNUSED_DESC
Definition: ecma_167.h:153
#define VDS_POS_UNALLOC_SPACE_DESC
Definition: udf_rel.h:98
extent_ad nextVolDescSeqExt
Definition: ecma_167.h:227
static NTSTATUS ReadBytes(IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
Definition: detect.c:67
OSSTATUS UDFVerifySequence(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb, IN uint32 block, IN uint32 lastblock, OUT lb_addr *fileset)
Definition: mount.cpp:2461
#define DbgFreePool
Definition: env_spec_w32.h:334
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 MyAllocatePool__(type, size)
Definition: mem_tools.h:149
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
r l[0]
Definition: byte_order.h:167
#define UDFSetUsedBits(arr, bit, bc)
Definition: udf_info.h:1202
#define TID_LOGICAL_VOL_INTEGRITY_DESC
Definition: ecma_167.h:162
#define UDFSetZeroBit(arr, bit)
Definition: udf_info.h:1208
#define PARTITION_MAP_TYPE_2
Definition: ecma_167.h:302
#define UDFClrZeroBit(arr, bit)
Definition: udf_info.h:1209
#define UDF_SPARABLE_MAP15
Definition: osta_misc.h:95
uint8 identSuffix[8]
Definition: ecma_167.h:62
uint32 block
Definition: udf_rel.h:108
#define UDFGetBadBit(arr, bit)
Definition: udf_info.h:1205
#define d
Definition: ke_i.h:81
#define SPARING_LOC_AVAILABLE
Definition: osta_misc.h:195
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl eax
Definition: synth_sse3d.h:85
LONGLONG UDFTimeToNT(IN PUDF_TIME_STAMP UdfTime)
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx 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 mm1 mm5 paddd mm0 paddd mm4 mm0 mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 mm1 paddd mm0 mm0 packssdw mm0 movd eax movw edi esi edx edi
Definition: synth_sse3d.h:185
PEXTENT_MAP __fastcall UDFMergeMappings(IN PEXTENT_MAP Extent, IN PEXTENT_MAP Extent2)
Definition: extent.cpp:266
#define try_return(S)
Definition: cdprocs.h:2189
#define MRW_DMA_OFFSET
Definition: cdrw_hw.h:3199
#define UDF_VCB_IC_MRW_ADDR_PROBLEM
Definition: udf_common.h:510
EntityID domainIdent
Definition: ecma_167.h:282
#define Vcb
Definition: cdprocs.h:1425
#define PARTITION_CONTENTS_NSR03
Definition: ecma_167.h:265
#define MyFreePool__(addr)
Definition: mem_tools.h:152
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define BrutePoint()
Definition: env_spec_w32.h:504
struct _SPARING_TABLE SPARING_TABLE
#define EXTENT_NOT_RECORDED_ALLOCATED
Definition: ecma_167.h:368
void __fastcall UDFCompressUnicode(IN PUNICODE_STRING UName, IN OUT uint8 **_CS0, IN OUT PSIZE_T Length)
Definition: udf_info.cpp:240
unsigned char uint8
Definition: types.h:28
uint32 __fastcall UDFPartLen(PVCB Vcb, uint32 PartNum)
Definition: alloc.cpp:265
void __fastcall UDFGetDstring(IN OUT PUNICODE_STRING UName, IN dstring *Dest, IN uint32 Length)
Definition: mount.cpp:783
#define UDFExtentToMapping(e)
Definition: udf_info.h:181
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static struct proto Ext[]
Definition: mkg3states.c:87
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 UDFUmount__(IN PVCB Vcb)
Definition: mount.cpp:921
GLbitfield flags
Definition: glext.h:7161
#define TrackMap_FixMRWAddressing
Definition: cdrw_usr.h:1642
uint8 logicalVolContentsUse[32]
Definition: ecma_167.h:348
#define VDS_POS_RECURSION_COUNTER
Definition: udf_rel.h:104
uint8 dstring
Definition: ecma_167.h:20
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
dstring volSetIdent[128]
Definition: ecma_167.h:198
#define VRS_ISO9660_FOUND
Definition: udf_rel.h:114
#define UDF_ID_METADATA
Definition: osta_misc.h:277
#define TID_VOL_DESC_PTR
Definition: ecma_167.h:156
#define TID_ANCHOR_VOL_DESC_PTR
Definition: ecma_167.h:155
uint32 Offset
Definition: udf_rel.h:65
#define XCHG_DD(a, b)
Definition: mount.cpp:25
uint16 tagSerialNum
Definition: ecma_167.h:143
struct _UDFPartMap * PUDFPartMap
lba_t UDFFindAnchor(PVCB Vcb)
Definition: mount.cpp:1011
#define OS_SUCCESS(a)
Definition: env_spec_w32.h:56
#define UDF_VCB_ASSUME_ALL_USED
Definition: udf_common.h:474
#define VDS_POS_TERMINATING_DESC
Definition: udf_rel.h:103
#define UDF_LVID_TTL
Definition: udf_rel.h:517
uint32 logicalBlockSize
Definition: ecma_167.h:281
OSSTATUS UDFUpdateNonAllocated(IN PVCB Vcb)
Definition: mount.cpp:857
GLenum GLsizei len
Definition: glext.h:6722
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
#define TID_SPACE_BITMAP_DESC
Definition: ecma_167.h:173
#define NOTHING
Definition: env_spec_w32.h:461
struct _SPACE_BITMAP_DESC * PSPACE_BITMAP_DESC
ULONG UDFLocateLbaInExtent(IN PVCB Vcb, IN PEXTENT_MAP Extent, IN lba_t lba)
Definition: extent.cpp:116
#define AS_USED
Definition: udf_info.h:327
#define UDF_MAX_LVID_CHAIN_LENGTH
Definition: udf_rel.h:516
#define UDFMarkSpaceAsXXX(Vcb, FileInfo, Map, asXXX)
Definition: udf_info.h:322
uint32 extLength
Definition: ecma_167.h:128
uint32 volDescSeqNum
Definition: ecma_167.h:189
ULONG WCacheGetWriteBlockCount__(IN PW_CACHE Cache)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define CUR_IDENT_SZ
#define STD_ID_BEA01
Definition: ecma_167.h:80
struct _SparingEntry SparingEntry
uint16 flags
Definition: ecma_167.h:208
void UDFLoadFileset(IN PVCB Vcb, IN PFILE_SET_DESC fset, OUT lb_addr *root, OUT lb_addr *sysstream)
Definition: mount.cpp:2539
_SEH2_END
Definition: create.c:4424
uint32 primaryVolDescNum
Definition: ecma_167.h:190
OSSTATUS UDFReadVDS(IN PVCB Vcb, IN uint32 block, IN uint32 lastblock, IN PUDF_VDS_RECORD vds, IN int8 *Buf)
Definition: mount.cpp:2239
OSSTATUS UDFIsCachedBadSequence(IN PVCB Vcb, IN uint32 Lba)
Definition: mount.cpp:2569
uint8 logicalVolContentsUse[16]
Definition: ecma_167.h:283
uint32 __fastcall UDFPartEnd(PVCB Vcb, uint32 PartNum)
Definition: alloc.cpp:242
#define TID_LOGICAL_VOL_DESC
Definition: ecma_167.h:159
uint32 UDFFindVRS(PVCB Vcb)
Definition: mount.cpp:1108
Definition: sacdrv.h:267
unsigned short USHORT
Definition: pedump.c:61
#define SPARING_LOC_CORRUPTED
Definition: osta_misc.h:196
short_ad partitionIntegrityTable
Definition: ecma_167.h:417
#define PARTITION_CONTENTS_NSR02
Definition: ecma_167.h:264
unsigned short uint16
Definition: types.h:30
struct _PARTITION_HEADER_DESC * PPARTITION_HEADER_DESC
uint32 extPosition
Definition: ecma_167.h:408
VOID UDFRememberBadSequence(IN PVCB Vcb, IN uint32 Lba, IN OSSTATUS RC)
Definition: mount.cpp:2587
void __fastcall UDFDecompressUnicode(IN OUT PUNICODE_STRING UName, IN uint8 *CS0, IN SIZE_T Length, OUT uint16 *valueCRC)
Definition: udf_info.cpp:170
OSSTATUS UDFVerifyXSpaceBitmap(IN PVCB Vcb, IN uint32 PartNum, IN PSHORT_AD bm, IN ULONG bm_type)
Definition: mount.cpp:1667
uint8 stdIdent[STD_ID_LEN]
Definition: ecma_167.h:74
#define UDF_PART_DAMAGED_NO
Definition: udfpubl.h:122
#define VDS_POS_LOGICAL_VOL_DESC
Definition: udf_rel.h:99
_SEH2_FINALLY
Definition: create.c:4395
uint32 logicalBlockNum
Definition: ecma_167.h:362
#define min(a, b)
Definition: monoChain.cc:55
#define UDF_USER_FS_FLAGS_NEW_FS_RO
Definition: udfpubl.h:116
OSSTATUS UDFReadTagged(PVCB Vcb, int8 *Buf, uint32 Block, uint32 Location, uint16 *Ident)
Definition: udf_info.cpp:4586
#define UDFGetUsedBit(arr, bit)
Definition: udf_info.h:1198
#define UDF_PREALLOC_CLASS_DIR
Definition: udf_info.h:356
uint8 ident[23]
Definition: ecma_167.h:61
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
uint16 partitionReferenceNum
Definition: ecma_167.h:363
#define VRS_NSR02_FOUND
Definition: udf_rel.h:112
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
#define EXTENT_NEXT_EXTENT_ALLOCDESC
Definition: ecma_167.h:370
uint8 impUse[460]
Definition: ecma_167.h:238
#define UDF_MAX_READ_REVISION
Definition: udf_rel.h:513
OSSTATUS UDFUpdateLogicalVol(IN PVCB Vcb, IN UDF_VDS_RECORD Lba, IN PUNICODE_STRING VolIdent)
Definition: mount.cpp:598
#define UDF_CHECK_BITMAP_RESOURCE(Vcb)
Definition: udffs.h:264
#define WCACHE_MODE_R
Definition: wcache_lib.h:126
#define UDF_VIRTUAL_MAP15
Definition: osta_misc.h:93
#define STD_ID_LEN
Definition: ecma_167.h:71
timestamp recordingDateAndTime
Definition: ecma_167.h:204
#define OUT
Definition: typedefs.h:39
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:108
VOID UDFVFlush(IN PVCB Vcb)
Definition: remap.cpp:742
#define INTEGRITY_TYPE_OPEN
Definition: ecma_167.h:357
#define TID_IMP_USE_VOL_DESC
Definition: ecma_167.h:157
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
#define UDFGetZeroBit(arr, bit)
Definition: udf_info.h:1207
OSSTATUS WCacheFlushBlocks__(IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba, IN ULONG BCount)
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
unsigned int ULONG
Definition: retypes.h:1
#define UDFAllocFreeExtent(v, l, ss, sl, e, af)
Definition: udf_info.h:347
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define STD_ID_TEA01
Definition: ecma_167.h:86
void UDFReadEntityID_Domain(PVCB Vcb, EntityID *eID)
Definition: udf_info.cpp:1559
#define UDFGetFreeBit(arr, bit)
Definition: udf_info.h:1199
short_ad unallocatedSpaceTable
Definition: ecma_167.h:415
uint32 lba_t
Definition: platform.h:20
#define UDFGetPartNumByPartNdx(Vcb, pi)
Definition: udf_info.h:1028
uint32 __fastcall UDFGetPartNumByPhysLba(IN PVCB Vcb, IN uint32 Lba)
Definition: alloc.cpp:201
GLfloat GLfloat p
Definition: glext.h:8902
#define UDF_ID_VIRTUAL
Definition: osta_misc.h:275
#define TID_FILE_ENTRY
Definition: ecma_167.h:170
#define EXTENT_FLAG_ALLOC_SEQUENTIAL
Definition: udf_rel.h:77
static void push(calc_node_t *op)
Definition: rpn_ieee.c:113
OSSTATUS UDFProcessSequence(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb, IN uint32 block, IN uint32 lastblock, OUT lb_addr *fileset)
Definition: mount.cpp:2360
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define UDFSetUsedBit(arr, bit)
Definition: udf_info.h:1200
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
uint16 maxVolSeqNum
Definition: ecma_167.h:193
static SERVICE_STATUS status
Definition: service.c:31
#define UDF_EXTENT_LENGTH_MASK
Definition: osta_misc.h:148
SIZE_T __stdcall UDFGetBitmapLen(uint32 *Bitmap, SIZE_T Offs, SIZE_T Lim)
Definition: alloc.cpp:496
uint32 UDFPhysLbaToPart(IN PVCB Vcb, IN uint32 PartNum, IN uint32 Addr)
Definition: alloc.cpp:46
OSSTATUS UDFLoadVAT(IN PVCB Vcb, IN uint32 PartNdx)
Definition: udf_info.cpp:3602
#define TID_FILE_SET_DESC
Definition: ecma_167.h:165
int k
Definition: mpi.c:3369
dstring volIdent[32]
Definition: ecma_167.h:191
uint16 descCRCLength
Definition: ecma_167.h:145
#define UDFReadSectors(Vcb, Translate, Lba, BCount, Direct, Buffer, ReadBytes)
Definition: phys_lib.h:126
OSSTATUS UDFFindLastFileSet(IN PVCB Vcb, IN lb_addr *Addr, IN OUT PFILE_SET_DESC FileSetDesc)
Definition: mount.cpp:2739
uint8 partitionMapLength
Definition: ecma_167.h:295
OSSTATUS WCacheSetMode__(IN PW_CACHE Cache, IN ULONG Mode)
#define RELOC_MAP_GRAN
Definition: udf_rel.h:119
#define VDS_POS_VOL_DESC_PTR
Definition: udf_rel.h:102
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
short_ad freedSpaceTable
Definition: ecma_167.h:418
#define UDF_TYPE1_MAP15
Definition: osta_misc.h:92
char int8
Definition: platform.h:10
VOID UDFPreClrModified(IN PVCB Vcb)
Definition: misc_common.cpp:18
#define LBA_OUT_OF_EXTENT
Definition: udf_rel.h:426
VOID UDFClrModified(IN PVCB Vcb)
Definition: misc_common.cpp:26
Definition: ps.c:97