ReactOS 0.4.15-dev-7961-gdcf9eb0
udf_info.cpp
Go to the documentation of this file.
1
2// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3// All rights reserved
4// This file was released under the GPLv2 on June 2015.
6/*
7 Module name:
8
9 udf_info.cpp
10
11 Abstract:
12
13 This file contains filesystem-specific routines
14
15*/
16
17#include "udf.h"
18
19#define UDF_BUG_CHECK_ID UDF_FILE_UDF_INFO
20
21#ifdef _X86_
22static const int8 valid_char_arr[] =
23 {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
24 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
25 1,0,1,0, 0,0,0,0, 0,0,1,1, 1,0,0,1,
26 0,0,0,0, 0,0,0,0, 0,0,1,1, 1,1,1,1,
27 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // @ABCDE....
28 0,0,0,0, 0,0,0,0, 0,0,0,1, 1,1,0,0, // ....Z[/]^_
29 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // `abcde....
30 0,0,0,0, 0,0,0,0, 0,0,0,1, 1,1,0,1, // ....z{|}~
31
32 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
33 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
34 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
35 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
36 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
37 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
38 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
39 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
40#else // NO X86 optimization , use generic C/C++
41static const char valid_char_arr[] = {"*/:?\"<>|\\"};
42#endif // _X86_
43
44#define DOS_CRC_MODULUS 41
45#define hexChar crcChar
46static const char crcChar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ#_~-@";
47
48/* Used to convert hex digits to ASCII for readability. */
49//static const char hexChar[] = "0123456789ABCDEF";
50
51static const uint16 CrcTable[256] = {
52 0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50a5U, 0x60c6U, 0x70e7U,
53 0x8108U, 0x9129U, 0xa14aU, 0xb16bU, 0xc18cU, 0xd1adU, 0xe1ceU, 0xf1efU,
54 0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52b5U, 0x4294U, 0x72f7U, 0x62d6U,
55 0x9339U, 0x8318U, 0xb37bU, 0xa35aU, 0xd3bdU, 0xc39cU, 0xf3ffU, 0xe3deU,
56 0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64e6U, 0x74c7U, 0x44a4U, 0x5485U,
57 0xa56aU, 0xb54bU, 0x8528U, 0x9509U, 0xe5eeU, 0xf5cfU, 0xc5acU, 0xd58dU,
58 0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76d7U, 0x66f6U, 0x5695U, 0x46b4U,
59 0xb75bU, 0xa77aU, 0x9719U, 0x8738U, 0xf7dfU, 0xe7feU, 0xd79dU, 0xc7bcU,
60 0x48c4U, 0x58e5U, 0x6886U, 0x78a7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U,
61 0xc9ccU, 0xd9edU, 0xe98eU, 0xf9afU, 0x8948U, 0x9969U, 0xa90aU, 0xb92bU,
62 0x5af5U, 0x4ad4U, 0x7ab7U, 0x6a96U, 0x1a71U, 0x0a50U, 0x3a33U, 0x2a12U,
63 0xdbfdU, 0xcbdcU, 0xfbbfU, 0xeb9eU, 0x9b79U, 0x8b58U, 0xbb3bU, 0xab1aU,
64 0x6ca6U, 0x7c87U, 0x4ce4U, 0x5cc5U, 0x2c22U, 0x3c03U, 0x0c60U, 0x1c41U,
65 0xedaeU, 0xfd8fU, 0xcdecU, 0xddcdU, 0xad2aU, 0xbd0bU, 0x8d68U, 0x9d49U,
66 0x7e97U, 0x6eb6U, 0x5ed5U, 0x4ef4U, 0x3e13U, 0x2e32U, 0x1e51U, 0x0e70U,
67 0xff9fU, 0xefbeU, 0xdfddU, 0xcffcU, 0xbf1bU, 0xaf3aU, 0x9f59U, 0x8f78U,
68 0x9188U, 0x81a9U, 0xb1caU, 0xa1ebU, 0xd10cU, 0xc12dU, 0xf14eU, 0xe16fU,
69 0x1080U, 0x00a1U, 0x30c2U, 0x20e3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U,
70 0x83b9U, 0x9398U, 0xa3fbU, 0xb3daU, 0xc33dU, 0xd31cU, 0xe37fU, 0xf35eU,
71 0x02b1U, 0x1290U, 0x22f3U, 0x32d2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U,
72 0xb5eaU, 0xa5cbU, 0x95a8U, 0x8589U, 0xf56eU, 0xe54fU, 0xd52cU, 0xc50dU,
73 0x34e2U, 0x24c3U, 0x14a0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U,
74 0xa7dbU, 0xb7faU, 0x8799U, 0x97b8U, 0xe75fU, 0xf77eU, 0xc71dU, 0xd73cU,
75 0x26d3U, 0x36f2U, 0x0691U, 0x16b0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U,
76 0xd94cU, 0xc96dU, 0xf90eU, 0xe92fU, 0x99c8U, 0x89e9U, 0xb98aU, 0xa9abU,
77 0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18c0U, 0x08e1U, 0x3882U, 0x28a3U,
78 0xcb7dU, 0xdb5cU, 0xeb3fU, 0xfb1eU, 0x8bf9U, 0x9bd8U, 0xabbbU, 0xbb9aU,
79 0x4a75U, 0x5a54U, 0x6a37U, 0x7a16U, 0x0af1U, 0x1ad0U, 0x2ab3U, 0x3a92U,
80 0xfd2eU, 0xed0fU, 0xdd6cU, 0xcd4dU, 0xbdaaU, 0xad8bU, 0x9de8U, 0x8dc9U,
81 0x7c26U, 0x6c07U, 0x5c64U, 0x4c45U, 0x3ca2U, 0x2c83U, 0x1ce0U, 0x0cc1U,
82 0xef1fU, 0xff3eU, 0xcf5dU, 0xdf7cU, 0xaf9bU, 0xbfbaU, 0x8fd9U, 0x9ff8U,
83 0x6e17U, 0x7e36U, 0x4e55U, 0x5e74U, 0x2e93U, 0x3eb2U, 0x0ed1U, 0x1ef0U
84};
85
86static const uint32 crc32_tab[] = {
87 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
88 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
89 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
90 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
91 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
92 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
93 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
94 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
95 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
96 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
97 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
98 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
99 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
100 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
101 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
102 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
103 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
104 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
105 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
106 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
107 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
108 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
109 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
110 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
111 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
112 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
113 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
114 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
115 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
116 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
117 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
118 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
119 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
120 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
121 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
122 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
123 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
124 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
125 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
126 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
127 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
128 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
129 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
130 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
131 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
132 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
133 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
134 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
135 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
136 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
137 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
138 0x2d02ef8dL
139};
140
141/*
142 This routine allocates new memory block, copies data there & free old one
143*/
144/*uint32
145UDFMemRealloc(
146 int8* OldBuff,
147 uint32 OldLength,
148 int8** NewBuff,
149 uint32 NewLength
150 )
151{
152 int8* new_buff;
153
154 (*NewBuff) = OldBuff;
155 if(OldLength == NewLength) return OldLength;
156 new_buff = (int8*)MyAllocatePool__(NonPagedPool, NewLength);
157 if(!new_buff) return 0;
158 if(OldLength > NewLength) OldLength = NewLength;
159 RtlCopyMemory(new_buff, OldBuff, OldLength);
160 MyFreePool__(OldBuff);
161 (*NewBuff) = new_buff;
162 return OldLength;
163} // end UDFMemRealloc()*/
164
165/*
166 This routine converts compressed Unicode to standard
167 */
168void
171 IN OUT PUNICODE_STRING UName,
172 IN uint8* CS0,
174 OUT uint16* valueCRC
175 )
176{
177 uint16 compID = CS0[0];
178 uint32 unicodeIndex = 0;
179 uint32 byteIndex = 1;
180 PWCHAR buff;
181 uint8* _CS0 = CS0+1;
182
183 if(!Length) goto return_empty_str;
184 // First check for valid compID.
185 switch(compID) {
186 case UDF_COMP_ID_8: {
187
189 if(!buff) goto return_empty_str;
190 UName->Buffer = buff;
191
192 // Loop through all the bytes.
193 while (byteIndex < Length) {
194 (*buff) = (*_CS0);
195 _CS0++;
196 byteIndex++;
197 buff++;
198 }
199 unicodeIndex = byteIndex-1;
200 break;
201 }
202 case UDF_COMP_ID_16: {
203
205 if(!buff) goto return_empty_str;
206 UName->Buffer = buff;
207
208 // Loop through all the bytes.
209 while (byteIndex < Length) {
210 // Move the first byte to the high bits of the unicode char.
211 *buff = ((*_CS0) << 8) | (*(_CS0+1));
212 _CS0+=2;
213 byteIndex+=2;
214 unicodeIndex++;
215 buff++;
216 ASSERT(byteIndex <= Length);
217 }
218 break;
219 }
220 default: {
221return_empty_str:
222 UName->Buffer = NULL;
223 UName->MaximumLength =
224 UName->Length = 0;
225 return;
226 }
227 }
228 UName->MaximumLength = (UName->Length = (((uint16)unicodeIndex)*sizeof(WCHAR))) + sizeof(WCHAR);
229 UName->Buffer[unicodeIndex] = 0;
230 if(valueCRC) {
231 *valueCRC = UDFCrc(CS0+1, Length-1);
232 }
233} // end UDFDecompressUnicode()
234
235/*
236 This routine converts standard Unicode to compressed
237 */
238void
241 IN PUNICODE_STRING UName,
242 IN OUT uint8** _CS0,
244 )
245{
246 uint8* CS0;
247 uint8 compID;
248 uint16 unicodeIndex;
249 uint32 i, len;
250 PWCHAR Buff;
251
252 len = (UName->Length) / sizeof(WCHAR);
253 compID = (!len) ? 0 : UDF_COMP_ID_8;
254 // check for uncompressable characters
255 Buff = UName->Buffer;
256 for(i=0; i<len; i++, Buff++) {
257 if((*Buff) & 0xff00) {
258 compID = UDF_COMP_ID_16;
259 break;
260 }
261 }
262
263 CS0 = (uint8*)MyAllocatePool__(NonPagedPool, *Length = (((compID==UDF_COMP_ID_8) ? 1 : 2)*len + 1) );
264 if(!CS0) return;
265
266 CS0[0] = compID;
267 *_CS0 = CS0;
268 // init loop
269 CS0++;
270 unicodeIndex = 0;
271 Buff = UName->Buffer;
272 if(compID == UDF_COMP_ID_16) {
273 // Loop through all the bytes.
274 while (unicodeIndex < len) {
275 // Move the 2nd byte to the low bits of the compressed unicode char.
276 *CS0 = (uint8)((*Buff) >> 8);
277 CS0++;
278 *CS0 = (uint8)(*Buff);
279 CS0++;
280 Buff++;
281 unicodeIndex++;
282 }
283 } else {
284 // Loop through all the bytes.
285 while (unicodeIndex < len) {
286 *CS0 = (uint8)(*Buff);
287 CS0++;
288 Buff++;
289 unicodeIndex++;
290 }
291 }
292} // end UDFCompressUnicode()
293
294/*
295OSSTATUS UDFFindFile__(IN PVCB Vcb,
296 IN BOOLEAN IgnoreCase,
297 IN PUNICODE_STRING Name,
298 IN PUDF_FILE_INFO DirInfo)
299 see 'Udf_info.h'
300*/
301
302/*
303 This routine reads (Extended)FileEntry according to FileDesc
304 */
307 IN PVCB Vcb,
308 IN long_ad* Icb,
309 IN OUT PFILE_ENTRY FileEntry, // here we can also get ExtendedFileEntry
310 IN OUT uint16* Ident
311 )
312{
314
315 if(!OS_SUCCESS(status = UDFReadTagged(Vcb, (int8*)FileEntry,
316 UDFPartLbaToPhys(Vcb,&(Icb->extLocation)),
317 Icb->extLocation.logicalBlockNum,
318 Ident))) return status;
319 if((FileEntry->descTag.tagIdent != TID_FILE_ENTRY) &&
320 (FileEntry->descTag.tagIdent != TID_EXTENDED_FILE_ENTRY)) {
321 UDFPrint((" Not a FileEntry (lbn=%x, tag=%x)\n", Icb->extLocation.logicalBlockNum, FileEntry->descTag.tagIdent));
323 }
324 return STATUS_SUCCESS;
325} // UDFReadFileEntry()
326
327#if !defined (_X86_) || !defined (_MSC_VER)
328/*
329 Decides if a Unicode character matches one of a list
330 of ASCII characters.
331 Used by DOS version of UDFIsIllegalChar for readability, since all of the
332 illegal characters above 0x0020 are in the ASCII subset of Unicode.
333 Works very similarly to the standard C function strchr().
334 */
337 IN uint8* string, // String to search through.
338 IN WCHAR ch // Unicode char to search for.
339 )
340{
341 BOOLEAN found = FALSE;
342
343 while(*string != '\0' && !found) {
344 // These types should compare, since both are unsigned numbers.
345 if(*string == ch) {
346 found = TRUE;
347 }
348 string++;
349 }
350 return(found);
351} // end UDFUnicodeInString()
352#endif // _X86_
353
354/*
355 Decides whether character passed is an illegal character for a
356 DOS file name.
357*/
358#ifdef _MSC_VER
359#pragma warning(push)
360#pragma warning(disable:4035) // re-enable below
361#endif
362
363#ifdef _X86_
364#ifdef _MSC_VER
365__declspec (naked)
366#endif
367#endif // _X86_
371 IN WCHAR chr // ECX
372 )
373{
374 // Genuine illegal char's for DOS.
375#if defined (_X86_) && defined (_MSC_VER)
376 _asm {
377 push ebx
378
379 xor eax,eax
380// mov ax,chr
381 mov ax,cx
382 or ah,ah
383 jnz ERR_IIC
384
385 lea ebx,[valid_char_arr]
386 xlatb
387 jmp short ERR_IIC2
388ERR_IIC:
389 mov al,1
390ERR_IIC2:
391
392 pop ebx
393 ret
394 }
395
396#else // NO X86 optimization , use generic C/C++
397 /* FIXME */
398 //return ((ch < 0x20) || UDFUnicodeInString((uint8*)&valid_char_arr, ch));
399 return ((chr < 0x20) || UDFUnicodeInString((uint8*)&valid_char_arr, chr));
400#endif // _X86_
401} // end UDFIsIllegalChar()
402
403#ifdef _MSC_VER
404#pragma warning(pop) // re-enable warning #4035
405#endif
406
407/*
408 Translate udfName to dosName using OSTA compliant.
409 dosName must be a unicode string with min length of 12.
410 */
411
412/*void UDFDOSName__(
413 IN PVCB Vcb,
414 IN OUT PUNICODE_STRING DosName,
415 IN PUNICODE_STRING UdfName,
416 IN PUDF_FILE_INFO FileInfo
417 )
418{
419 BOOLEAN KeepIntact;
420
421 KeepIntact = (FileInfo && (FileInfo->Index < 2));
422 UDFDOSName(Vcb, DosName, UdfName, KeepIntact);
423}*/
424
425void
428 IN PVCB Vcb,
430 IN PUNICODE_STRING UdfName,
431 IN BOOLEAN KeepIntact
432 )
433{
434#ifndef _CONSOLE
435 if(Vcb->CompatFlags & UDF_VCB_IC_OS_NATIVE_DOS_NAME) {
436 UDFDOSNameOsNative(DosName, UdfName, KeepIntact);
437 return;
438 }
439#endif //_CONSOLE
440
441 switch(Vcb->CurrentUDFRev) {
442 case 0x0100:
443 case 0x0101:
444 case 0x0102:
445 UDFDOSName100(DosName, UdfName, KeepIntact);
446 break;
447
448 case 0x0150:
449 // in general, we need bytes-from-media to
450 // create valid UDF 1.50 name.
451 // Curently it is impossible, thus, we'll use
452 // UDF 2.00 translation algorithm
453 case 0x0200:
454 UDFDOSName200(DosName, UdfName, KeepIntact, Vcb->CurrentUDFRev == 0x0150);
455 break;
456
457 case 0x0201:
458 default:
459 UDFDOSName201(DosName, UdfName, KeepIntact);
460 }
461}
462
463void
467 IN PUNICODE_STRING UdfName,
468 IN BOOLEAN KeepIntact
469 )
470{
471 PWCHAR dosName = DosName->Buffer;
472 PWCHAR udfName = UdfName->Buffer;
473 uint32 udfLen = UdfName->Length / sizeof(WCHAR);
474
475 uint32 index, dosIndex = 0, extIndex = 0, lastPeriodIndex;
476 BOOLEAN needsCRC = FALSE, hasExt = FALSE, writingExt = FALSE, isParent = FALSE;
477 uint32 valueCRC;
479
480 if(KeepIntact &&
481 (udfLen <= 2) && (udfName[0] == UNICODE_PERIOD)) {
482 isParent = TRUE;
483 if((udfLen == 2) && (udfName[1] != UNICODE_PERIOD))
484 isParent = FALSE;
485 }
486
487 for (index = 0 ; index < udfLen ; index++) {
488 current = udfName[index];
489 if (current == UNICODE_PERIOD && !isParent) {
490 if (dosIndex==0 || hasExt) {
491 // Ignore leading periods or any other than used for extension.
492 needsCRC = TRUE;
493 } else {
494 // First, find last character which is NOT a period or space.
495 lastPeriodIndex = udfLen - 1;
496 while(lastPeriodIndex >=0 &&
497 (udfName[lastPeriodIndex] == UNICODE_PERIOD ||
498 udfName[lastPeriodIndex] == UNICODE_SPACE))
499 lastPeriodIndex--;
500 // Now search for last remaining period.
501 while(lastPeriodIndex >= 0 &&
502 udfName[lastPeriodIndex] != UNICODE_PERIOD)
503 lastPeriodIndex--;
504 // See if the period we found was the last or not.
505 if (lastPeriodIndex != index)
506 needsCRC = TRUE; // If not, name needs translation.
507 // As long as the period was not trailing,
508 // the file name has an extension.
509 if (lastPeriodIndex >= 0) hasExt = TRUE;
510 }
511 } else {
512 if ((!hasExt && dosIndex == DOS_NAME_LEN) ||
513 extIndex == DOS_EXT_LEN) {
514 // File name or extension is too long for DOS.
515 needsCRC = TRUE;
516 } else {
517 if (current == UNICODE_SPACE) { // Ignore spaces.
518 needsCRC = TRUE;
519 } else {
520 // Look for illegal or unprintable characters.
521 if (UDFIsIllegalChar(current) /*|| !UnicodeIsPrint(current)*/) {
522 needsCRC = TRUE;
524 /* Skip Illegal characters(even spaces),
525 * but not periods.
526 */
527 while(index+1 < udfLen &&
528 (UDFIsIllegalChar(udfName[index+1]) /*||
529 !UnicodeIsPrint(udfName[index+1])*/) &&
530 udfName[index+1] != UNICODE_PERIOD)
531 index++;
532 }
533 // Add current char to either file name or ext.
534 if (writingExt) {
535 ext[extIndex] = current;
536 extIndex++;
537 } else {
538 dosName[dosIndex] = current;
539 dosIndex++;
540 }
541 }
542 }
543 }
544 // See if we are done with file name, either because we reached
545 // the end of the file name length, or the final period.
546 if (!writingExt && hasExt && (dosIndex == DOS_NAME_LEN ||
547 index == lastPeriodIndex)) {
548 // If so, and the name has an extension, start reading it.
549 writingExt = TRUE;
550 // Extension starts after last period.
551 index = lastPeriodIndex;
552 }
553 }
554 //
555 if (needsCRC) {
556 // Add CRC to end of file name or at position 4.
557 if (dosIndex >4) dosIndex = 4;
558 valueCRC = UDFUnicodeCksum(udfName, udfLen);
559 // set CRC prefix
560 dosName[dosIndex] = UNICODE_CRC_MARK;
561 // Convert 12-bit CRC to hex characters.
562 dosName[dosIndex+1] = hexChar[(valueCRC & 0x0f00) >> 8];
563 dosName[dosIndex+2] = hexChar[(valueCRC & 0x00f0) >> 4];
564 dosName[dosIndex+3] = hexChar[(valueCRC & 0x000f)];
565 dosIndex+=4;
566 }
567 // Add extension, if any.
568 if (extIndex != 0) {
569 dosName[dosIndex] = UNICODE_PERIOD;
570 dosIndex++;
571 for (index = 0; index < extIndex; index++) {
572 dosName[dosIndex] = ext[index];
573 dosIndex++;
574 }
575 }
576 DosName->Length = (uint16)dosIndex*sizeof(WCHAR);
578} // end UDFDOSName100()
579
580void
584 IN PUNICODE_STRING UdfName,
585 IN BOOLEAN KeepIntact,
586 IN BOOLEAN Mode150
587 )
588{
589 PWCHAR dosName = DosName->Buffer;
590 PWCHAR udfName = UdfName->Buffer;
591 uint32 udfLen = UdfName->Length / sizeof(WCHAR);
592
593 uint32 index, dosIndex = 0, extIndex = 0, lastPeriodIndex;
594 BOOLEAN needsCRC = FALSE, hasExt = FALSE, writingExt = FALSE, isParent = FALSE;
595 uint32 valueCRC;
597
598 if(KeepIntact &&
599 (udfLen <= 2) && (udfName[0] == UNICODE_PERIOD)) {
600 isParent = TRUE;
601 if((udfLen == 2) && (udfName[1] != UNICODE_PERIOD))
602 isParent = FALSE;
603 }
604
605 for (index = 0 ; index < udfLen ; index++) {
606 current = udfName[index];
607 if (current == UNICODE_PERIOD && !isParent) {
608 if (dosIndex==0 || hasExt) {
609 // Ignore leading periods or any other than used for extension.
610 needsCRC = TRUE;
611 } else {
612 // First, find last character which is NOT a period or space.
613 lastPeriodIndex = udfLen - 1;
614 while(lastPeriodIndex >=0 &&
615 (udfName[lastPeriodIndex] == UNICODE_PERIOD ||
616 udfName[lastPeriodIndex] == UNICODE_SPACE))
617 lastPeriodIndex--;
618 // Now search for last remaining period.
619 while(lastPeriodIndex >= 0 &&
620 udfName[lastPeriodIndex] != UNICODE_PERIOD)
621 lastPeriodIndex--;
622 // See if the period we found was the last or not.
623 if (lastPeriodIndex != index)
624 needsCRC = TRUE; // If not, name needs translation.
625 // As long as the period was not trailing,
626 // the file name has an extension.
627 if (lastPeriodIndex >= 0) hasExt = TRUE;
628 }
629 } else {
630 if ((!hasExt && dosIndex == DOS_NAME_LEN) ||
631 extIndex == DOS_EXT_LEN) {
632 // File name or extension is too long for DOS.
633 needsCRC = TRUE;
634 } else {
635 if (current == UNICODE_SPACE) { // Ignore spaces.
636 needsCRC = TRUE;
637 } else {
638 // Look for illegal or unprintable characters.
639 if (UDFIsIllegalChar(current) /*|| !UnicodeIsPrint(current)*/) {
640 needsCRC = TRUE;
642 /* Skip Illegal characters(even spaces),
643 * but not periods.
644 */
645 while(index+1 < udfLen &&
646 (UDFIsIllegalChar(udfName[index+1]) /*||
647 !UnicodeIsPrint(udfName[index+1])*/) &&
648 udfName[index+1] != UNICODE_PERIOD)
649 index++;
650 }
651 // Add current char to either file name or ext.
652 if (writingExt) {
653 ext[extIndex] = current;
654 extIndex++;
655 } else {
656 dosName[dosIndex] = current;
657 dosIndex++;
658 }
659 }
660 }
661 }
662 // See if we are done with file name, either because we reached
663 // the end of the file name length, or the final period.
664 if (!writingExt && hasExt && (dosIndex == DOS_NAME_LEN ||
665 index == lastPeriodIndex)) {
666 // If so, and the name has an extension, start reading it.
667 writingExt = TRUE;
668 // Extension starts after last period.
669 index = lastPeriodIndex;
670 }
671 }
672 // Now handle CRC if needed.
673 if (needsCRC) {
674 // Add CRC to end of file name or at position 4.
675 if (dosIndex >4) dosIndex = 4;
676 valueCRC = Mode150 ? UDFUnicodeCksum150(udfName, udfLen) : UDFUnicodeCksum(udfName, udfLen);
677 // Convert 16-bit CRC to hex characters.
678 dosName[dosIndex] = hexChar[(valueCRC & 0xf000) >> 12];
679 dosName[dosIndex+1] = hexChar[(valueCRC & 0x0f00) >> 8];
680 dosName[dosIndex+2] = hexChar[(valueCRC & 0x00f0) >> 4];
681 dosName[dosIndex+3] = hexChar[(valueCRC & 0x000f)];
682 dosIndex+=4;
683 }
684 // Add extension, if any.
685 if (extIndex != 0) {
686 dosName[dosIndex] = UNICODE_PERIOD;
687 dosIndex++;
688 for (index = 0; index < extIndex; index++) {
689 dosName[dosIndex] = ext[index];
690 dosIndex++;
691 }
692 }
693 DosName->Length = (uint16)dosIndex*sizeof(WCHAR);
695} // end UDFDOSName200()
696
697
698void
702 IN PUNICODE_STRING UdfName,
703 IN BOOLEAN KeepIntact
704 )
705{
706 PWCHAR dosName = DosName->Buffer;
707 PWCHAR udfName = UdfName->Buffer;
708 uint16 udfLen = UdfName->Length / sizeof(WCHAR);
709
710 uint16 index, dosIndex = 0;
711 //uint16 extIndex = 0;
712 BOOLEAN needsCRC = FALSE, isParent = FALSE;
713 //BOOLEAN hasExt = FALSE, writingExt = FALSE;
714 uint16 valueCRC;
717
718 if(KeepIntact &&
719 (udfLen <= 2) && (udfName[0] == UNICODE_PERIOD)) {
720 isParent = TRUE;
721 if((udfLen == 2) && (udfName[1] != UNICODE_PERIOD))
722 isParent = FALSE;
723 }
724
725 #define DOS_CRC_LEN 4
726 #define DOS_CRC_MODULUS 41
727
728 int16 crcIndex;
729 uint16 extLen;
730 uint16 nameLen;
731 uint16 charLen;
732 int16 overlayBytes;
733 int16 bytesLeft;
734
735 /* Start at the end of the UDF file name and scan for a period */
736 /* ('.'). This will be where the DOS extension starts (if */
737 /* any). */
738 index = udfLen;
739 while (index-- > 0) {
740 if (udfName[index] == '.')
741 break;
742 }
743 if ((index < 0) || isParent) {
744 /* There name was scanned to the beginning of the buffer */
745 /* and no extension was found. */
746 extLen = 0;
747 nameLen = udfLen;
748 } else {
749 /* A DOS extension was found, process it first. */
750 extLen = udfLen - index - 1;
751 nameLen = index;
752 dosIndex = 0;
753 bytesLeft = DOS_EXT_LEN;
754 while (++index < udfLen && bytesLeft > 0) {
755 /* Get the current character and convert it to upper */
756 /* case. */
757 current = udfName[index];
758 if (current == ' ') {
759 /* If a space is found, a CRC must be appended to */
760 /* the mangled file name. */
761 needsCRC = TRUE;
762 } else {
763 /* Determine if this is a valid file name char and */
764 /* calculate its corresponding BCS character byte */
765 /* length (zero if the char is not legal or */
766 /* undisplayable on this system). */
767
768 charLen = (UDFIsIllegalChar(current)
769 /*|| !UnicodeIsPrint(current)*/) ? 0 : 1;
770
771 /* If the char is larger than the available space */
772 /* in the buffer, pretend it is undisplayable. */
773 if (charLen > bytesLeft)
774 charLen = 0;
775 if (charLen == 0) {
776 /* Undisplayable or illegal characters are */
777 /* substituted with an underscore ("_"), and */
778 /* required a CRC code appended to the mangled */
779 /* file name. */
780 needsCRC = TRUE;
781 charLen = 1;
782 current = '_';
783 /* Skip over any following undiplayable or */
784 /* illegal chars. */
785 while (index +1 <udfLen &&
786 (UDFIsIllegalChar(udfName[index+1])
787 /*|| !UnicodeIsPrint(udfName[index+1])*/))
788 index++;
789 }
790 /* Assign the resulting char to the next index in */
791 /* the extension buffer and determine how many BCS */
792 /* bytes are left. */
793 ext[dosIndex++] = current;
794 bytesLeft -= charLen;
795 }
796 }
797 /* Save the number of Unicode characters in the extension */
798 extLen = dosIndex;
799 /* If the extension was too large, or it was zero length */
800 /* (i.e. the name ended in a period), a CRC code must be */
801 /* appended to the mangled name. */
802 if (index < udfLen || extLen == 0)
803 needsCRC = TRUE;
804 }
805 /* Now process the actual file name. */
806 index = 0;
807 dosIndex = 0;
808 crcIndex = 0;
809 overlayBytes = -1;
810 bytesLeft = DOS_NAME_LEN;
811 while (index < nameLen && bytesLeft > 0) {
812 /* Get the current character and convert it to upper case. */
813 current = udfName[index];
814 if (current ==' ' || (current == '.' && !isParent) ) {
815 /* Spaces and periods are just skipped, a CRC code */
816 /* must be added to the mangled file name. */
817 needsCRC = TRUE;
818 } else {
819 /* Determine if this is a valid file name char and */
820 /* calculate its corresponding BCS character byte */
821 /* length (zero if the char is not legal or */
822 /* undisplayable on this system). */
823
824 charLen = (UDFIsIllegalChar(current)
825 /*|| !UnicodeIsPrint(current)*/) ? 0 : 1;
826
827 /* If the char is larger than the available space in */
828 /* the buffer, pretend it is undisplayable. */
829 if (charLen > bytesLeft)
830 charLen = 0;
831
832 if (charLen == 0) {
833 /* Undisplayable or illegal characters are */
834 /* substituted with an underscore ("_"), and */
835 /* required a CRC code appended to the mangled */
836 /* file name. */
837 needsCRC = TRUE;
838 charLen = 1;
839 current = '_';
840 /* Skip over any following undisplayable or illegal */
841 /* chars. */
842 while (index +1 <nameLen &&
843 (UDFIsIllegalChar(udfName[index+1])
844 /*|| !UnicodeIsPrint(udfName[index+1])*/))
845 index++;
846 /* Terminate loop if at the end of the file name. */
847 if (index >= nameLen)
848 break;
849 }
850 /* Assign the resulting char to the next index in the */
851 /* file name buffer and determine how many BCS bytes */
852 /* are left. */
853 dosName[dosIndex++] = current;
854 bytesLeft -= charLen;
855 /* This figures out where the CRC code needs to start */
856 /* in the file name buffer. */
857 if (bytesLeft >= DOS_CRC_LEN) {
858 /* If there is enough space left, just tack it */
859 /* onto the end. */
860 crcIndex = dosIndex;
861 } else {
862 /* If there is not enough space left, the CRC */
863 /* must overlay a character already in the file */
864 /* name buffer. Once this condition has been */
865 /* met, the value will not change. */
866 if (overlayBytes < 0) {
867 /* Determine the index and save the length of */
868 /* the BCS character that is overlayed. It */
869 /* is possible that the CRC might overlay */
870 /* half of a two-byte BCS character depending */
871 /* upon how the character boundaries line up. */
872 overlayBytes = (bytesLeft + charLen > DOS_CRC_LEN)?1 :0;
873 crcIndex = dosIndex - 1;
874 }
875 }
876 }
877 /* Advance to the next character. */
878 index++;
879 }
880 /* If the scan did not reach the end of the file name, or the */
881 /* length of the file name is zero, a CRC code is needed. */
882 if (index < nameLen || index == 0)
883 needsCRC = TRUE;
884
885 /* If the name has illegal characters or and extension, it */
886 /* is not a DOS device name. */
887
888/* if (needsCRC == FALSE && extLen == 0) { */
889 /* If this is the name of a DOS device, a CRC code should */
890 /* be appended to the file name.
891 if (IsDeviceName(udfName, udfLen))
892 needsCRC = TRUE;
893 }*/
894
895 /* Append the CRC code to the file name, if needed. */
896 if (needsCRC) {
897 /* Get the CRC value for the original Unicode string */
898 valueCRC = UDFUnicodeCksum(udfName, udfLen);
899
900 /* begin. */
901 dosIndex = crcIndex;
902 /* If the character being overlayed is a two-byte BCS */
903 /* character, replace the first byte with an underscore. */
904 if (overlayBytes > 0)
905 dosName[dosIndex++] = '_';
906 /* Append the encoded CRC value with delimiter. */
907 dosName[dosIndex++] = '#';
908 dosName[dosIndex++] =
910 valueCRC %= DOS_CRC_MODULUS * DOS_CRC_MODULUS;
911 dosName[dosIndex++] =
912 crcChar[valueCRC / DOS_CRC_MODULUS];
913 valueCRC %= DOS_CRC_MODULUS;
914 dosName[dosIndex++] = crcChar[valueCRC];
915 }
916 /* Append the extension, if any. */
917 if (extLen > 0) {
918 /* Tack on a period and each successive byte in the */
919 /* extension buffer. */
920 dosName[dosIndex++] = '.';
921 for (index = 0; index < extLen; index++)
922 dosName[dosIndex++] = ext[index];
923 }
924 /* Return the length of the resulting Unicode string. */
925 DosName->Length = (uint16)dosIndex*sizeof(WCHAR);
927
928} // end UDFDOSName201()
929
930#ifndef UDF_READ_ONLY_BUILD
931/*
932 This routine initializes Tag structure. It must be called after all
933 manual settings to generate valid CRC & Checksum
934 */
935void
937 IN PVCB Vcb,
938 IN tag* Tag,
939 IN uint16 DataLen, // total length of descriptor _including_ icbTag
940 IN uint32 TagLoc
941 )
942{
943 uint32 i;
944 int8* tb;
945
946 AdPrint(("UDF: SetTag Loc=%x(%x), tagIdent=%x\n", TagLoc, Tag->tagLocation, Tag->tagIdent));
947
948 if(DataLen) DataLen -= sizeof(tag);
949// int8* Data = ((int8*)Tag) + sizeof(tag);
950 // Ecma-167 states, that all implementations
951 // shall set this field to '3' even if
952 // disc contains descriptors recorded with
953 // value '2'
954 // But we should ignore this to make happy othe UDF implementations :(
955 Tag->descVersion = (Vcb->NSRDesc & VRS_NSR03_FOUND) ? 3 : 2;
956 Tag->tagLocation = TagLoc;
957 Tag->tagSerialNum = (uint16)(Vcb->SerialNumber + 1);
958 Tag->descCRCLength = DataLen;
959 Tag->descCRC = UDFCrc((uint8*)(Tag+1), DataLen);
960 Tag->tagChecksum = 0;
961 tb = ((int8*)Tag);
962 for (i=0; i<sizeof(tag); i++,tb++)
963 Tag->tagChecksum += (i!=4) ? (*tb) : 0;
964} // end UDFSetUpTag()
965
966/*
967 This routine builds FileEntry & associated AllocDescs for specified
968 extent.
969 */
972 IN PVCB Vcb,
973 IN PUDF_FILE_INFO DirInfo,
975 IN uint32 PartNum,
976 IN uint16 AllocMode, // short/long/ext/in-icb
977 IN uint32 ExtAttrSz,
978 IN BOOLEAN Extended
979 )
980{
981 PFILE_ENTRY FileEntry;
983// EntityID* eID;
984 uint32 l;
985 EXTENT_INFO _FEExtInfo;
986 uint16* lcp;
987
988 ASSERT(!PartNum);
989 ASSERT(!ExtAttrSz);
990 // calculate the length required
991 l = (Extended ? sizeof(EXTENDED_FILE_ENTRY) : sizeof(FILE_ENTRY)) + ExtAttrSz;
992 if(l > Vcb->LBlockSize) return STATUS_INVALID_PARAMETER;
993 // allocate block for FE
994 if(!OS_SUCCESS(status = UDFAllocateFESpace(Vcb, DirInfo, PartNum, &_FEExtInfo, l) ))
995 return status;
996 // remember FE location for future hard link creation
997 ASSERT(UDFFindDloc(Vcb, _FEExtInfo.Mapping[0].extLocation) == (-1));
998 if(!OS_SUCCESS(status = UDFStoreDloc(Vcb, FileInfo, _FEExtInfo.Mapping[0].extLocation))) {
1000 UDFFreeFESpace(Vcb, DirInfo, &_FEExtInfo); // free
1001 MyFreePool__(_FEExtInfo.Mapping);
1002 return status;
1003 }
1005 if(!FileEntry) {
1006 UDFRemoveDloc(Vcb, FileInfo->Dloc);
1007 FileInfo->Dloc = NULL;
1008 UDFFreeFESpace(Vcb, DirInfo, &_FEExtInfo); // free
1009 MyFreePool__(_FEExtInfo.Mapping);
1011 }
1012 FileInfo->Dloc->FELoc = _FEExtInfo;
1013
1014 RtlZeroMemory((int8*)FileEntry, l);
1015 // set up in-memory FE structure
1016 FileEntry->icbTag.flags = AllocMode;
1018 FileEntry->icbTag.numEntries = 1;
1019// if(DirInfo && DirInfo->Dloc && DirInfo->Dloc
1020 FileEntry->icbTag.strategyType = 4;
1021// FileEntry->icbTag.strategyParameter = 0;
1022 FileEntry->descTag.tagIdent = Extended ? TID_EXTENDED_FILE_ENTRY : TID_FILE_ENTRY;
1023 FileEntry->descTag.tagLocation = UDFPhysLbaToPart(Vcb, PartNum, _FEExtInfo.Mapping[0].extLocation);
1024 FileEntry->uid = Vcb->DefaultUID;
1025 FileEntry->gid = Vcb->DefaultGID;
1026
1027 if(Extended) {
1028// eID = &(((PEXTENDED_FILE_ENTRY)FileEntry)->impIdent);
1029 lcp = &(((PEXTENDED_FILE_ENTRY)FileEntry)->fileLinkCount);
1030 ((PEXTENDED_FILE_ENTRY)FileEntry)->checkpoint = 1;
1031 } else {
1032// eID = &(FileEntry->impIdent);
1033 lcp = &(FileEntry->fileLinkCount);
1034 ((PFILE_ENTRY)FileEntry)->checkpoint = 1;
1035 }
1036
1037#if 0
1039#endif
1040
1041 /*RtlCopyMemory((int8*)&(eID->ident), UDF_ID_DEVELOPER, sizeof(UDF_ID_DEVELOPER) );
1042 iis = (impIdentSuffix*)&(eID->identSuffix);
1043 iis->OSClass = UDF_OS_CLASS_WINNT;
1044 iis->OSIdent = UDF_OS_ID_WINNT;*/
1045
1046 *lcp = 0xffff;
1047
1048 FileInfo->Dloc->FileEntry = (tag*)FileEntry;
1049 FileInfo->Dloc->FileEntryLen = l;
1050
1051 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
1052
1053 return STATUS_SUCCESS;
1054} // end UDFBuildFileEntry()
1055#endif //UDF_READ_ONLY_BUILD
1056
1057/*
1058 This routine builds ExtentInfo for specified (Ex)FileEntry & associated
1059 AllocDescs
1060 */
1063 IN PVCB Vcb,
1064 IN PFILE_ENTRY fe,
1065 IN PLONG_AD fe_loc,
1066 IN OUT PEXTENT_INFO FExtInfo, // user data
1067 IN OUT PEXTENT_INFO AExtInfo // alloc descs
1068 )
1069{
1070 EXTENT_AD TmpExt;
1071
1072 UDFPrint((" UDFLoadExtInfo:\n"));
1073 FExtInfo->Mapping = UDFReadMappingFromXEntry(Vcb, fe_loc->extLocation.partitionReferenceNum,
1074 (tag*)fe, &(FExtInfo->Offset), AExtInfo);
1075 if(!(FExtInfo->Mapping)) {
1076 if(!(FExtInfo->Offset))
1077 return STATUS_UNSUCCESSFUL;
1078 TmpExt.extLength = fe_loc->extLength;
1079 TmpExt.extLocation = UDFPartLbaToPhys(Vcb, &(fe_loc->extLocation));
1080 if(TmpExt.extLocation == LBA_OUT_OF_EXTENT)
1082 FExtInfo->Mapping = UDFExtentToMapping(&TmpExt);
1083 }
1084 if(fe->descTag.tagIdent == TID_FILE_ENTRY) {
1085// UDFPrint(("Standard FileEntry\n"));
1086 FExtInfo->Length = fe->informationLength;
1087 } else /*if(fe->descTag.tagIdent == TID_EXTENDED_FILE_ENTRY) */ {
1088 FExtInfo->Length = ((PEXTENDED_FILE_ENTRY)fe)->informationLength;
1089 }
1090 UDFPrint((" FExtInfo->Length %x\n", FExtInfo->Length));
1091 ASSERT(FExtInfo->Length <= UDFGetExtentLength(FExtInfo->Mapping));
1092 FExtInfo->Modified = FALSE;
1093
1094 return STATUS_SUCCESS;
1095} // end UDFLoadExtInfo()
1096
1097/*
1098 This routine builds FileIdent for specified FileEntry.
1099 We shall call UDFSetUpTag after all other initializations
1100 This structure is a precise copy of on-disk FileIdent
1101 structure. All modifications of it (including memory block
1102 size) are reflected on Directory extent. This, allocation of
1103 too long block (without changes in ImpUseLen) will lead to
1104 unreadable Directory
1105 */
1108 IN PVCB Vcb,
1110 IN PLONG_AD FileEntryIcb, // virtual address of FileEntry
1111 IN uint32 ImpUseLen,
1112 OUT PFILE_IDENT_DESC* _FileId,
1113 OUT uint32* FileIdLen
1114 )
1115{
1116 PFILE_IDENT_DESC FileId;
1117 uint8* CS0;
1118 SIZE_T Nlen;
1119 uint32 l;
1120 // prepare filename
1121 UDFCompressUnicode(fn, &CS0, &Nlen);
1122 if(!CS0) return STATUS_INSUFFICIENT_RESOURCES;
1123 if(Nlen < 2) {
1124 Nlen = 0;
1125 } else
1126 if(Nlen > UDF_NAME_LEN) {
1127 if(CS0) MyFreePool__(CS0);
1129 }
1130 // allocate memory for FI
1131 l = (sizeof(FILE_IDENT_DESC) + Nlen + ImpUseLen + 3) & ~((uint32)3);
1133 if(!FileId) {
1134 if(CS0) MyFreePool__(CS0);
1136 }
1137 // fill FI structure
1138 RtlZeroMemory( (int8*)FileId, l);
1139 RtlCopyMemory( ((int8*)(FileId+1))+ImpUseLen, CS0, Nlen);
1141 FileId->fileVersionNum = 1;
1142 FileId->lengthOfImpUse = (uint16)ImpUseLen;
1143 FileId->lengthFileIdent = (uint8)Nlen;
1144 FileId->icb = *FileEntryIcb;
1145 *_FileId = FileId;
1146 *FileIdLen = l;
1147
1148 if(CS0) MyFreePool__(CS0);
1149 return STATUS_SUCCESS;
1150} // end UDFBuildFileIdent()
1151
1152#ifndef UDF_READ_ONLY_BUILD
1153/*
1154 This routine sets informationLength field in (Ext)FileEntry
1155 */
1156void
1159 IN int64 Size
1160 )
1161{
1162 uint16 Ident;
1163// PDIR_INDEX_ITEM DirIndex;
1164
1166 AdPrint(("UDFSetFileSize: %I64x, FI %x\n", Size, FileInfo));
1167
1168 //AdPrint((" Dloc %x\n", FileInfo->Dloc));
1169 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
1170 //AdPrint((" FileEntry %x\n", FileInfo->Dloc->FileEntry));
1171 Ident = FileInfo->Dloc->FileEntry->tagIdent;
1172 //AdPrint((" Ident %x\n", Ident));
1173 if(Ident == TID_FILE_ENTRY) {
1174 PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
1175 //AdPrint((" fe %x\n", fe));
1176 fe->informationLength = Size;
1177 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1178 PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
1179 //AdPrint((" ext-fe %x\n", fe));
1180 fe->informationLength = Size;
1181 }
1182/* if(DirIndex = UDFDirIndex(UDFGetDirIndexByFileInfo(FileInfo),FileInfo->Index) ) {
1183 DirIndex->FileSize = Size;
1184 }*/
1185 //AdPrint(("UDFSetFileSize: ok\n"));
1186 return;
1187} // end UDFSetFileSize()
1188
1189void
1191 IN PVCB Vcb,
1193 IN int64* ASize
1194 )
1195{
1196 uint16 Ident;
1197 PDIR_INDEX_ITEM DirIndex;
1198
1200 if(ASize) {
1201 AdPrint(("UDFSetFileSizeInDirNdx: %I64x\n", *ASize));
1202 } else {
1203 AdPrint(("UDFSetFileSizeInDirNdx: sync\n"));
1204 }
1205
1207 if(!DirIndex)
1208 return;
1209
1210 Ident = FileInfo->Dloc->FileEntry->tagIdent;
1211 if(Ident == TID_FILE_ENTRY) {
1212 PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
1213 DirIndex->FileSize = fe->informationLength;
1214 if(ASize) {
1215 DirIndex->AllocationSize = *ASize;
1216// } else {
1217// DirIndex->AllocationSize = (fe->informationLength + Vcb->LBlockSize - 1) & ~(Vcb->LBlockSize - 1);
1218 }
1219 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1220 PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
1221 DirIndex->FileSize = fe->informationLength;
1222 if(ASize) {
1223 DirIndex->AllocationSize = *ASize;
1224// } else {
1225// DirIndex->AllocationSize = (fe->informationLength + Vcb->LBlockSize - 1) & ~(Vcb->LBlockSize - 1);
1226 }
1227 }
1228 return;
1229} // end UDFSetFileSizeInDirNdx()
1230#endif //UDF_READ_ONLY_BUILD
1231
1232/*
1233 This routine gets informationLength field in (Ext)FileEntry
1234 */
1235int64
1238 )
1239{
1240 uint16 Ident;
1241
1243
1244 Ident = FileInfo->Dloc->FileEntry->tagIdent;
1245 if(Ident == TID_FILE_ENTRY) {
1246 PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
1247 return fe->informationLength;
1248 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1249 PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
1250 return fe->informationLength;
1251 }
1252 return (-1);
1253} // end UDFGetFileSize()
1254
1255int64
1257 IN PVCB Vcb,
1259 )
1260{
1261 PDIR_INDEX_ITEM DirIndex;
1262
1264
1266 if(!DirIndex)
1267 return -1;
1268
1269 return DirIndex->FileSize;
1270} // end UDFGetFileSizeFromDirNdx()
1271
1272#ifndef UDF_READ_ONLY_BUILD
1273/*
1274 This routine sets lengthAllocDesc field in (Ext)FileEntry
1275 */
1276void
1278 IN PVCB Vcb,
1280 )
1281{
1282 uint16 Ident;
1283
1285
1286 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
1287 Ident = FileInfo->Dloc->FileEntry->tagIdent;
1288 if(Ident == TID_FILE_ENTRY) {
1289 PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
1290 if(FileInfo->Dloc->AllocLoc.Length) {
1291 fe->lengthAllocDescs = min(FileInfo->Dloc->AllocLoc.Mapping[0].extLength -
1292 FileInfo->Dloc->AllocLoc.Offset,
1293 (uint32)(FileInfo->Dloc->AllocLoc.Length));
1294 } else
1295 if(Vcb->CompatFlags & UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS) {
1296 fe->lengthAllocDescs = (uint32)(FileInfo->Dloc->DataLoc.Length);
1297 }
1298 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1299 PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
1300 if(FileInfo->Dloc->AllocLoc.Length) {
1301 fe->lengthAllocDescs = min(FileInfo->Dloc->AllocLoc.Mapping[0].extLength -
1302 FileInfo->Dloc->AllocLoc.Offset,
1303 (uint32)(FileInfo->Dloc->AllocLoc.Length));
1304 } else
1305 if(Vcb->CompatFlags & UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS) {
1306 fe->lengthAllocDescs = (uint32)(FileInfo->Dloc->DataLoc.Length);
1307 }
1308 }
1309} // end UDFSetAllocDescLen()
1310
1311/*
1312 This routine changes fileLinkCount field in (Ext)FileEntry
1313 */
1314void
1317 IN BOOLEAN Increase
1318 )
1319{
1320 uint16 Ident;
1321
1323
1324 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
1325 Ident = FileInfo->Dloc->FileEntry->tagIdent;
1326 if(Ident == TID_FILE_ENTRY) {
1327 PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
1328 if(Increase) {
1329 fe->fileLinkCount++;
1330 } else {
1331 fe->fileLinkCount--;
1332 }
1333 if(fe->fileLinkCount & 0x8000)
1334 fe->fileLinkCount = 0xffff;
1335 return;
1336 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1337 PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
1338 if(Increase) {
1339 fe->fileLinkCount++;
1340 } else {
1341 fe->fileLinkCount--;
1342 }
1343 if(fe->fileLinkCount & 0x8000)
1344 fe->fileLinkCount = 0xffff;
1345 return;
1346 }
1347 return;
1348} // end UDFChangeFileLinkCount()
1349#endif //UDF_READ_ONLY_BUILD
1350
1351/*
1352 This routine gets fileLinkCount field from (Ext)FileEntry
1353 */
1354uint16
1357 )
1358{
1359 uint16 Ident;
1360 uint16 d;
1361
1363
1364 if(!FileInfo->Dloc->FileEntry)
1365 return 1;
1366 Ident = FileInfo->Dloc->FileEntry->tagIdent;
1367 // UDF engine assumes that LinkCount is a counter
1368 // of FileIdents, referencing this FE.
1369 // UDF 2.0 states, that it should be counter of ALL
1370 // references (including SDir) - 1.
1371 // Thus we'll write to media UDF-required value, but return
1372 // cooked value to callers
1373 d = UDFHasAStreamDir(FileInfo) ? 0 : 1;
1374 if(Ident == TID_FILE_ENTRY) {
1375 return ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->fileLinkCount + d;
1376 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1377 return ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->fileLinkCount + d;
1378 }
1380} // end UDFGetFileLinkCount()
1381
1382#ifdef UDF_CHECK_UTIL
1383/*
1384 This routine sets fileLinkCount field in (Ext)FileEntry
1385 */
1386void
1387UDFSetFileLinkCount(
1389 uint16 LinkCount
1390 )
1391{
1392 uint16 Ident;
1393 uint16 d;
1394
1396
1397 if(!FileInfo->Dloc->FileEntry)
1398 return;
1399 Ident = FileInfo->Dloc->FileEntry->tagIdent;
1400 // UDF engine assumes that LinkCount is a counter
1401 // of FileIdents, referencing this FE.
1402 // UDF 2.0 states, that it should be counter of ALL
1403 // references (including SDir) - 1.
1404 // Thus we'll write to media UDF-required value, but return
1405 // cooked value to callers
1406 d = UDFHasAStreamDir(FileInfo) ? 0 : 1;
1407 if(Ident == TID_FILE_ENTRY) {
1408 ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->fileLinkCount = LinkCount - d;
1409 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1410 ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->fileLinkCount = LinkCount - d;
1411 }
1412 return;
1413} // end UDFGetFileLinkCount()
1414#endif //UDF_CHECK_UTIL
1415
1416/*
1417 This routine gets lengthExtendedAttr field in (Ext)FileEntry
1418 */
1419uint32
1422 )
1423{
1424 uint16 Ident;
1425
1427
1428 if(!FileInfo->Dloc->FileEntry)
1429 return 1;
1430 Ident = FileInfo->Dloc->FileEntry->tagIdent;
1431
1432 if(Ident == TID_FILE_ENTRY) {
1433 return ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->lengthExtendedAttr;
1434 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1435 return ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->lengthExtendedAttr;
1436 }
1437 return 0;
1438} // end UDFGetFileEALength()
1439
1440#ifndef UDF_READ_ONLY_BUILD
1441/*
1442 This routine sets UniqueID field in (Ext)FileEntry
1443 */
1444int64
1446 IN PVCB Vcb
1447 )
1448{
1449 Vcb->NextUniqueId++;
1450 if(!((uint32)(Vcb->NextUniqueId)))
1451 Vcb->NextUniqueId += 16;
1452 return Vcb->NextUniqueId;
1453}
1454
1455void
1457 IN PVCB Vcb,
1459 )
1460{
1461 uint16 Ident;
1462 int64 UID;
1463
1465
1467
1468/* UID = FileInfo->Dloc->FELoc.Mapping[0].extLocation |
1469 ( FileInfo->ParentFile ? (((int64)(FileInfo->ParentFile->Dloc->FELoc.Mapping[0].extLocation)) << 32) : 0);*/
1470
1471 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
1472 Ident = FileInfo->Dloc->FileEntry->tagIdent;
1473 if(Ident == TID_FILE_ENTRY) {
1474 PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
1475 fe->uniqueID = UID;
1476 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1477 PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
1478 fe->uniqueID = UID;
1479 }
1480 if(FileInfo->FileIdent)
1481 ((FidADImpUse*)&(FileInfo->FileIdent->icb.impUse))->uniqueID = (uint32)UID;
1482 return;
1483} // end UDFSetFileUID()
1484#endif //UDF_READ_ONLY_BUILD
1485
1486/*
1487 This routine gets UniqueID field in (Ext)FileEntry
1488 */
1489__inline
1490int64
1492 IN tag* FileEntry
1493 )
1494{
1495 uint16 Ident;
1496
1497 Ident = FileEntry->tagIdent;
1498 if(Ident == TID_FILE_ENTRY) {
1499 PFILE_ENTRY fe = (PFILE_ENTRY)(FileEntry);
1500 return fe->uniqueID;
1501 } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
1503 return fe->uniqueID;
1504 }
1505 return (-1);
1506} // end UDFGetFileUID()
1507
1508int64
1511 )
1512{
1514
1515 return UDFGetFileUID_(FileInfo->Dloc->FileEntry);
1516} // end UDFGetFileUID()
1517
1518#ifndef UDF_READ_ONLY_BUILD
1519void
1521 IN PVCB Vcb,
1522 IN BOOLEAN FileCounter,
1523 IN BOOLEAN Increase
1524 )
1525{
1526 uint32* counter;
1527
1528 counter = FileCounter ?
1529 &(Vcb->numFiles) :
1530 &(Vcb->numDirs);
1531 if(*counter == (ULONG)-1)
1532 return;
1533 if(Increase) {
1535 } else {
1537 }
1538
1539} // end UDFChangeFileCounter()
1540
1541void
1543 IN EntityID* eID,
1544 IN uint8* Str,
1545 IN uint32 Len
1546 )
1547{
1548 impIdentSuffix* iis;
1549
1550 RtlCopyMemory( (int8*)&(eID->ident), Str, Len );
1551 iis = (impIdentSuffix*)&(eID->identSuffix);
1553 iis->OSIdent = UDF_OS_ID_WINNT;
1554
1555} // end UDFSetEntityID_imp_()
1556#endif //UDF_READ_ONLY_BUILD
1557
1558void
1560 PVCB Vcb,
1561 EntityID* eID
1562 )
1563{
1564 domainIdentSuffix* dis;
1565 uint8 flags;
1566
1567 dis = (domainIdentSuffix*)&(eID->identSuffix);
1568
1569 UDFPrint(("UDF: Entity Id:\n"));
1570 UDFPrint(("flags: %x\n", eID->flags));
1571 UDFPrint(("ident[0]: %x\n", eID->ident[0]));
1572 UDFPrint(("ident[1]: %x\n", eID->ident[1]));
1573 UDFPrint(("ident[2]: %x\n", eID->ident[2]));
1574 UDFPrint(("ident[3]: %x\n", eID->ident[3]));
1575 UDFPrint(("UDF: Entity Id Domain:\n"));
1576 // Get current UDF revision
1577 Vcb->CurrentUDFRev = max(dis->currentRev, Vcb->CurrentUDFRev);
1578 UDFPrint(("Effective Revision: %x\n", Vcb->CurrentUDFRev));
1579 // Get Read-Only flags
1580 flags = dis->flags;
1581 UDFPrint(("Flags: %x\n", flags));
1583 (Vcb->CompatFlags & UDF_VCB_IC_SOFT_RO)) {
1585 Vcb->UserFSFlags |= UDF_USER_FS_FLAGS_SOFT_RO;
1586 UDFPrint((" Soft-RO\n"));
1587 }
1589 (Vcb->CompatFlags & UDF_VCB_IC_HW_RO)) {
1591 Vcb->UserFSFlags |= UDF_USER_FS_FLAGS_HW_RO;
1592 UDFPrint((" Hard-RO\n"));
1593 }
1594
1595} // end UDFReadEntityID_Domain()
1596
1597#ifndef UDF_READ_ONLY_BUILD
1598/*
1599 This routine writes data to file & increases it if necessary.
1600 In case of increasing AllocDescs will be rebuilt & flushed to disc
1601 (via driver's cache, of cource). Free space map will be updated only
1602 durring global media flush.
1603 */
1606 IN PVCB Vcb,
1608 IN int64 Offset,
1610 IN BOOLEAN Direct,
1611 IN int8* Buffer,
1612 OUT PSIZE_T WrittenBytes
1613 )
1614{
1615 int64 t, elen;
1617 int8* OldInIcb = NULL;
1620 SIZE_T _WrittenBytes;
1621 PUDF_DATALOC_INFO Dloc;
1622 // unwind staff
1623 BOOLEAN WasInIcb = FALSE;
1624 uint64 OldLen;
1625
1626// ASSERT(FileInfo->RefCount >= 1);
1627
1628 Dloc = FileInfo->Dloc;
1629 ASSERT(Dloc->FELoc.Mapping[0].extLocation);
1631 (*WrittenBytes) = 0;
1632
1633 AdPrint(("UDFWriteFile__ FE %x, FileInfo %x, ExtInfo %x, Mapping %x\n",
1634 Dloc->FELoc.Mapping[0].extLocation, FileInfo, &(Dloc->DataLoc), Dloc->DataLoc.Mapping));
1635
1636 t = Offset + Length;
1637// UDFUpdateModifyTime(Vcb, FileInfo);
1638 if(t <= Dloc->DataLoc.Length) {
1639 // write Alloc-Rec area
1640 ExtPrint((" WAlloc-Rec: %I64x <= %I64x\n", t, Dloc->DataLoc.Length));
1641 status = UDFWriteExtent(Vcb, &(Dloc->DataLoc), Offset, Length, Direct, Buffer, WrittenBytes);
1642 return status;
1643 }
1644 elen = UDFGetExtentLength(Dloc->DataLoc.Mapping);
1645 ExtPrint((" DataLoc Offs %x, Len %I64x\n",
1646 Dloc->DataLoc.Offset, Dloc->DataLoc.Length));
1647 if(t <= (elen - Dloc->DataLoc.Offset)) {
1648 // write Alloc-Not-Rec area
1649 ExtPrint((" WAlloc-Not-Rec: %I64x <= %I64x (%I64x - %I64x)\n",
1650 t, elen - Dloc->DataLoc.Offset - Dloc->DataLoc.Length,
1651 elen - Dloc->DataLoc.Offset,
1652 Dloc->DataLoc.Length));
1654 if(Vcb->CompatFlags & UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS) {
1655 ExtPrint((" w2k-compat -> rebuild allocs\n"));
1656 Dloc->DataLoc.Modified = TRUE;
1657 } else
1658 if((ULONG)((elen+Vcb->LBlockSize-1) >> Vcb->LBlockSizeBits) != (ULONG)((t+Vcb->LBlockSize-1) >> Vcb->LBlockSizeBits)) {
1659 ExtPrint((" LBS boundary crossed -> rebuild allocs\n"));
1660 Dloc->DataLoc.Modified = TRUE;
1661 }
1662 Dloc->DataLoc.Length = t;
1663 return UDFWriteExtent(Vcb, &(Dloc->DataLoc), Offset, Length, Direct, Buffer, WrittenBytes);
1664 }
1665 // We should not get here if Direct=TRUE
1666 if(Direct) return STATUS_INVALID_PARAMETER;
1667 OldLen = Dloc->DataLoc.Length;
1668 if(Dloc->DataLoc.Offset && Dloc->DataLoc.Length) {
1669 // read in-icb data. it'll be replaced after resize
1670 ExtPrint((" read in-icb data\n"));
1671 OldInIcb = (int8*)MyAllocatePool__(NonPagedPool, (uint32)(Dloc->DataLoc.Length));
1672 if(!OldInIcb) return STATUS_INSUFFICIENT_RESOURCES;
1673 status = UDFReadExtent(Vcb, &(Dloc->DataLoc), 0, (uint32)OldLen, FALSE, OldInIcb, &ReadBytes);
1674 if(!OS_SUCCESS(status)) {
1675 MyFreePool__(OldInIcb);
1676 return status;
1677 }
1678 }
1679 // init Alloc mode
1680 ExtPrint((" init Alloc mode\n"));
1681 if((((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK) == ICB_FLAG_AD_IN_ICB) {
1682 ((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags &= ~ICB_FLAG_ALLOC_MASK;
1683 ((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags |= Vcb->DefaultAllocMode;
1684 WasInIcb = TRUE;
1685 }
1686 // increase extent
1687 ExtPrint((" %s %s %s\n",
1688 UDFIsADirectory(FileInfo) ? "DIR" : "FILE",
1689 WasInIcb ? "In-Icb" : "",
1690 Vcb->LowFreeSpace ? "LowSpace" : ""));
1691 if(UDFIsADirectory(FileInfo) && !WasInIcb && !Vcb->LowFreeSpace) {
1692 FileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_ALLOC_SEQUENTIAL;
1693 status = UDFResizeExtent(Vcb, PartNum, (t*2+Vcb->WriteBlockSize-1) & ~(SIZE_T)(Vcb->WriteBlockSize-1), FALSE, &(Dloc->DataLoc));
1694 if(OS_SUCCESS(status)) {
1695 AdPrint((" preallocated space for Dir\n"));
1696 FileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_PREALLOCATED;
1697 //UDFSetFileSize(FileInfo, t);
1698 Dloc->DataLoc.Length = t;
1699 } else
1700 if(status == STATUS_DISK_FULL) {
1701 status = UDFResizeExtent(Vcb, PartNum, t, FALSE, &(Dloc->DataLoc));
1702 }
1703 } else {
1704 status = UDFResizeExtent(Vcb, PartNum, t, FALSE, &(Dloc->DataLoc));
1705 }
1706 ExtPrint((" DataLoc Offs %x, Len %I64x\n",
1707 Dloc->DataLoc.Offset, Dloc->DataLoc.Length));
1708 AdPrint(("UDFWriteFile__ (2) FileInfo %x, ExtInfo %x, Mapping %x\n", FileInfo, &(Dloc->DataLoc), Dloc->DataLoc.Mapping));
1709 if(!OS_SUCCESS(status)) {
1710 // rollback
1711 ExtPrint((" err -> rollback\n"));
1712 if(WasInIcb) {
1713 // restore Alloc mode
1714 ((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags &= ~ICB_FLAG_ALLOC_MASK;
1715 ((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags |= ICB_FLAG_AD_IN_ICB;
1716 if(Dloc->AllocLoc.Mapping) {
1718 Dloc->AllocLoc.Mapping = NULL;
1719 }
1720 }
1721 if(OldInIcb) {
1722 UDFWriteExtent(Vcb, &(Dloc->DataLoc), 0, (uint32)OldLen, FALSE, OldInIcb, &_WrittenBytes);
1723 MyFreePool__(OldInIcb);
1724 }
1725 if((int64)OldLen != Dloc->DataLoc.Length) {
1726 // restore file size
1727 AdPrint((" restore alloc\n"));
1728 FileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_CUT_PREALLOCATED;
1729 UDFResizeExtent(Vcb, PartNum, OldLen, FALSE, &(Dloc->DataLoc));
1730 FileInfo->Dloc->DataLoc.Flags &= ~EXTENT_FLAG_CUT_PREALLOCATED;
1731 }
1732 return status;
1733 }
1734 if(OldInIcb) {
1735 // replace data from ICB (if any) & free buffer
1736 ExtPrint((" write old in-icd data\n"));
1737 status = UDFWriteExtent(Vcb, &(Dloc->DataLoc), 0, (uint32)OldLen, FALSE, OldInIcb, &_WrittenBytes);
1738 MyFreePool__(OldInIcb);
1739 if(!OS_SUCCESS(status))
1740 return status;
1741 }
1742 // ufff...
1743 // & now we'll write out data to well prepared extent...
1744 // ... like all normal people do...
1745 ExtPrint((" write user data\n"));
1746 if(!OS_SUCCESS(status = UDFWriteExtent(Vcb, &(Dloc->DataLoc), Offset, Length, FALSE, Buffer, WrittenBytes)))
1747 return status;
1749 Dloc->DataLoc.Modified = TRUE;
1750#ifdef UDF_DBG
1751 if(Vcb->CompatFlags & UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS) {
1752 ASSERT(UDFGetFileSize(FileInfo) <= UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping));
1753 } else {
1754 ASSERT(((UDFGetFileSize(FileInfo)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)) ==
1755 ((UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)));
1756 }
1757#endif // UDF_DBG
1758 return STATUS_SUCCESS;
1759} // end UDFWriteFile__()
1760
1761/*
1762 This routine marks file as deleted & decrements file link counter.
1763 It can optionaly free allocation space
1764 */
1767 IN PVCB Vcb,
1769 IN BOOLEAN FreeSpace
1770 )
1771{
1772 uint_di Index; // index of file to be deleted
1773 uint16 lc;
1774 PUDF_DATALOC_INFO Dloc;
1775 PUDF_FILE_INFO DirInfo;
1776 PUDF_FILE_INFO SDirInfo;
1777 PDIR_INDEX_HDR hDirNdx;
1778 PDIR_INDEX_HDR hCurDirNdx;
1779 PDIR_INDEX_ITEM DirNdx;
1781 BOOLEAN IsSDir;
1782
1783 AdPrint(("UDFUnlinkFile__:\n"));
1784 if(!FileInfo) return STATUS_SUCCESS;
1785
1787
1788#ifndef _CONSOLE
1789 // now we can't call this if there is no OS-specific File Desc. present
1790 if(FileInfo->Fcb)
1792#endif //_CONSOLE
1793 // check references
1794 Dloc = FileInfo->Dloc;
1795 if((FileInfo->OpenCount /*> (uint32)(UDFHasAStreamDir(FileInfo) ? 1 : 0)*/) ||
1796 (FileInfo->RefCount>1)) return STATUS_CANNOT_DELETE;
1797 if(Dloc->SDirInfo)
1798 return STATUS_CANNOT_DELETE;
1799 ASSERT(FileInfo->RefCount == 1);
1800 DirInfo = FileInfo->ParentFile;
1801 // root dir or self
1802 if(!DirInfo || ((FileInfo->Index < 2) && !UDFIsAStreamDir(FileInfo))) return STATUS_CANNOT_DELETE;
1803 hDirNdx = DirInfo->Dloc->DirIndex;
1804 Index = FileInfo->Index;
1805 // we can't delete modified file
1806 // it should be closed & reopened (or flushed) before deletion
1807 DirNdx = UDFDirIndex(hDirNdx,Index);
1808#if defined UDF_DBG || defined PRINT_ALWAYS
1809 if(DirNdx && DirNdx->FName.Buffer) {
1810 AdPrint(("Unlink: %ws\n",DirNdx->FName.Buffer));
1811 }
1812#endif // UDF_DBG
1813 if(FreeSpace &&
1814 ((Dloc->FE_Flags & UDF_FE_FLAG_FE_MODIFIED) ||
1815 Dloc->DataLoc.Modified ||
1816 Dloc->AllocLoc.Modified ||
1817 Dloc->FELoc.Modified ||
1818 (DirNdx && (DirNdx->FI_Flags & UDF_FI_FLAG_FI_MODIFIED)) )) {
1819// BrutePoint();
1820 return STATUS_CANNOT_DELETE;
1821 }
1822 SDirInfo = Dloc->SDirInfo;
1823/* if(FreeSpace && SDirInfo) {
1824 UDFPrint(("Unlink: SDirInfo should be NULL !!!\n"));
1825 BrutePoint();
1826 return STATUS_CANNOT_DELETE;
1827 }*/
1828 // stream directory can be deleted even being not empty
1829 // otherwise we should perform some checks
1830 if(!(IsSDir = UDFIsAStreamDir(FileInfo))) {
1831 // check if not empty direcory
1832 if((DirNdx->FileCharacteristics & FILE_DIRECTORY) &&
1833 (hCurDirNdx = Dloc->DirIndex) &&
1834 FreeSpace) {
1835 if(!UDFIsDirEmpty(hCurDirNdx))
1837 }
1840 FileInfo->FileIdent->fileCharacteristics |= FILE_DELETED;
1841 hDirNdx->DelCount++;
1843 }
1844 UDFDecFileLinkCount(FileInfo); // decrease
1846 if(DirNdx && FreeSpace) {
1847 // FileIdent marked as 'deleted' should have an empty ICB
1848 // We shall do it only if object has parent Dir
1849 // (for ex. SDir has parent object, but has no parent Dir)
1851 DirNdx->FI_Flags &= ~UDF_FI_FLAG_SYS_ATTR;
1852 // Root Files (Root/SDir/Vat/etc.) has no FileIdent...
1853 if(FileInfo->FileIdent)
1854 RtlZeroMemory(&(FileInfo->FileIdent->icb), sizeof(long_ad));
1855 }
1856 // caller wishes to free allocation, but we can't do it due to
1857 // alive links. In this case we should just remove reference
1858 if(FreeSpace && lc) {
1859 ((icbtag*)(Dloc->FileEntry+1))->parentICBLocation.logicalBlockNum = 0;
1860 ((icbtag*)(Dloc->FileEntry+1))->parentICBLocation.partitionReferenceNum = 0;
1862 } else
1863 // if caller wishes to free file allocation &
1864 // there are no more references(links) to this file, lets do it >;->
1865 if(FreeSpace && !lc) {
1867 !UDFIsSDirDeleted(Dloc->SDirInfo) ) {
1868 // we have a Stream Dir associated...
1869 PUDF_FILE_INFO SFileInfo;
1870 // ... try to open it
1871 if(Dloc->SDirInfo) {
1873 return STATUS_CANNOT_DELETE;
1874 }
1875 // open SDir
1877 if(!OS_SUCCESS(status)) {
1878 // abort Unlink on error
1879 SFileInfo = Dloc->SDirInfo;
1880cleanup_SDir:
1881 UDFCleanUpFile__(Vcb, SFileInfo);
1882 if(SFileInfo) MyFreePool__(SFileInfo);
1884 return status;
1885 }
1886 SDirInfo = Dloc->SDirInfo;
1887 // try to perform deltree for Streams
1888 status = UDFUnlinkAllFilesInDir(Vcb, SDirInfo);
1889 if(!OS_SUCCESS(status)) {
1890 // abort Unlink on error
1891 UDFCloseFile__(Vcb, SDirInfo);
1892 SFileInfo = SDirInfo;
1893 BrutePoint();
1894 goto cleanup_SDir;
1895 }
1896 // delete SDir
1897 UDFFlushFile__(Vcb, SDirInfo);
1898 AdPrint((" "));
1899 UDFUnlinkFile__(Vcb, SDirInfo, TRUE);
1900 // close SDir
1901 UDFCloseFile__(Vcb, SDirInfo);
1902 if(UDFCleanUpFile__(Vcb, SDirInfo)) {
1903 MyFreePool__(SDirInfo);
1904#ifdef UDF_DBG
1905 } else {
1906 BrutePoint();
1907#endif // UDF_DBG
1908 }
1909 // update FileInfo
1910 ASSERT(Dloc->FileEntry);
1911 RtlZeroMemory( &(((PEXTENDED_FILE_ENTRY)(Dloc->FileEntry))->streamDirectoryICB), sizeof(long_ad));
1912 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
1913 } else
1914 if(IsSDir) {
1915 // do deltree for Streams
1917 if(!OS_SUCCESS(status)) {
1919 return status;
1920 }
1921 // update parent FileInfo
1922 ASSERT(FileInfo->ParentFile->Dloc->FileEntry);
1923 RtlZeroMemory( &(((PEXTENDED_FILE_ENTRY)(FileInfo->ParentFile->Dloc->FileEntry))->streamDirectoryICB), sizeof(long_ad));
1924 FileInfo->ParentFile->Dloc->FE_Flags &= ~UDF_FE_FLAG_HAS_SDIR;
1925 FileInfo->ParentFile->Dloc->FE_Flags |= (UDF_FE_FLAG_FE_MODIFIED |
1927 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_IS_DEL_SDIR;
1928 UDFDecFileLinkCount(FileInfo->ParentFile);
1929 }
1930 if(Dloc->DirIndex) {
1932 }
1933 // flush file
1935 UDFUnlinkDloc(Vcb, Dloc);
1936 // free allocation
1938 ASSERT(!(FileInfo->Dloc->FE_Flags & UDF_FE_FLAG_FE_MODIFIED));
1939 FileInfo->Dloc->FE_Flags &= ~UDF_FE_FLAG_FE_MODIFIED;
1940 }
1941 return STATUS_SUCCESS;
1942} // end UDFUnlinkFile__()
1943
1946 IN PVCB Vcb,
1947 IN PUDF_FILE_INFO DirInfo
1948 )
1949{
1950 PDIR_INDEX_HDR hCurDirNdx;
1951 PDIR_INDEX_ITEM CurDirNdx;
1954 uint_di i;
1955
1956 hCurDirNdx = DirInfo->Dloc->DirIndex;
1957 // check if we can delete all files
1958 for(i=2; (CurDirNdx = UDFDirIndex(hCurDirNdx,i)); i++) {
1959 // try to open Stream
1960 if(CurDirNdx->FileInfo)
1961 return STATUS_CANNOT_DELETE;
1962 }
1963 // start deletion
1964 for(i=2; (CurDirNdx = UDFDirIndex(hCurDirNdx,i)); i++) {
1965 // try to open Stream
1966 status = UDFOpenFile__(Vcb, FALSE, TRUE, NULL, DirInfo, &FileInfo, &i);
1968 // we should not release on-disk allocation for
1969 // deleted streams twice
1970 if(CurDirNdx->FileInfo) {
1971 BrutePoint();
1972 goto err_del_stream;
1973 }
1974 goto skip_del_stream;
1975 } else
1976 if(!OS_SUCCESS(status)) {
1977 // Error :(((
1978err_del_stream:
1980 if(FileInfo)
1982 return status;
1983 }
1984
1986 AdPrint((" "));
1989skip_del_stream:
1992 }
1993 }
1994 return STATUS_SUCCESS;
1995} // end UDFUnlinkAllFilesInDir()
1996#endif //UDF_READ_ONLY_BUILD
1997
1998/*
1999 This routine inits UDF_FILE_INFO structure for specified file
2000 If it returns status != STATUS_SUCCESS caller should call UDFCleanUpFile__
2001 for returned pointer *WITHOUT* using UDFCloseFile__
2002 */
2005 IN PVCB Vcb,
2007 IN BOOLEAN NotDeleted,
2009 IN PUDF_FILE_INFO DirInfo,
2010 OUT PUDF_FILE_INFO* _FileInfo,// this is to be filled & doesn't contain
2011 // any pointers
2012 IN uint_di* IndexToOpen
2013 )
2014{
2016 uint_di i=0;
2017 EXTENT_AD FEExt;
2018 uint16 Ident;
2019 PDIR_INDEX_HDR hDirNdx = DirInfo->Dloc->DirIndex;
2020 PDIR_INDEX_ITEM DirNdx;
2022 PUDF_FILE_INFO ParFileInfo;
2024 *_FileInfo = NULL;
2025 if(!hDirNdx) return STATUS_NOT_A_DIRECTORY;
2026
2027 // find specified file in directory index
2028 // if it is already known, skip this foolish code
2029 if(IndexToOpen) {
2030 i=*IndexToOpen;
2031 } else
2032 if(!OS_SUCCESS(status = UDFFindFile(Vcb, IgnoreCase, NotDeleted, fn, DirInfo, &i)))
2033 return status;
2034 // do this check for OpenByIndex
2035 // some routines may send invalid Index
2036 if(!(DirNdx = UDFDirIndex(hDirNdx,i)))
2038 if((FileInfo = DirNdx->FileInfo)) {
2039 // file is already opened.
2040 if((DirNdx->FileCharacteristics & FILE_DELETED) && NotDeleted) {
2041 AdPrint((" FILE_DELETED on open\n"));
2042 return STATUS_FILE_DELETED;
2043 }
2044 if((FileInfo->ParentFile != DirInfo) &&
2045 (FileInfo->Index >= 2)) {
2046 ParFileInfo = UDFLocateParallelFI(DirInfo, i, FileInfo);
2047 BrutePoint();
2048 if(ParFileInfo->ParentFile != DirInfo) {
2050 *_FileInfo = FileInfo;
2052 RtlCopyMemory(FileInfo, DirNdx->FileInfo, sizeof(UDF_FILE_INFO));
2053 // FileInfo->NextLinkedFile = DirNdx->FileInfo->NextLinkedFile; // is already done
2055 DirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
2056 FileInfo->RefCount = 0;
2057 FileInfo->ParentFile = DirInfo;
2058 FileInfo->Fcb = NULL;
2059 } else {
2060 FileInfo = ParFileInfo;
2061 }
2062 }
2063 // Just increase some counters & exit
2065
2066 ASSERT(FileInfo->ParentFile == DirInfo);
2068
2069 *_FileInfo = FileInfo;
2070 return STATUS_SUCCESS;
2071 } else
2072 if(IndexToOpen) {
2073 if((DirNdx->FileCharacteristics & FILE_DELETED) && NotDeleted) {
2074 AdPrint((" FILE_DELETED on open (2)\n"));
2075 return STATUS_FILE_DELETED;
2076 }
2077 }
2079 *_FileInfo = FileInfo;
2082 // init horizontal links
2083 FileInfo->NextLinkedFile =
2084 FileInfo->PrevLinkedFile = FileInfo;
2085 // read FileIdent
2087 if(!(FileInfo->FileIdent)) return STATUS_INSUFFICIENT_RESOURCES;
2088 FileInfo->FileIdentLen = DirNdx->Length;
2089 if(!OS_SUCCESS(status = UDFReadExtent(Vcb, &(DirInfo->Dloc->DataLoc), DirNdx->Offset,
2090 DirNdx->Length, FALSE, (int8*)(FileInfo->FileIdent), &ReadBytes) ))
2091 return status;
2092 if(FileInfo->FileIdent->descTag.tagIdent != TID_FILE_IDENT_DESC) {
2093 BrutePoint();
2095 }
2096 // check for opened links
2097 if(!OS_SUCCESS(status = UDFStoreDloc(Vcb, FileInfo, UDFPartLbaToPhys(Vcb, &(FileInfo->FileIdent->icb.extLocation)))))
2098 return status;
2099 // init pointer to parent object
2100 FileInfo->Index = i;
2101 FileInfo->ParentFile = DirInfo;
2102 // init pointers to linked files (if any)
2103 if(FileInfo->Dloc->LinkedFileInfo != FileInfo)
2104 UDFInsertLinkedFile(FileInfo, FileInfo->Dloc->LinkedFileInfo);
2105 if(FileInfo->Dloc->FileEntry)
2106 goto init_tree_entry;
2107 // read (Ex)FileEntry
2108 FileInfo->Dloc->FileEntry = (tag*)MyAllocatePoolTag__(NonPagedPool, Vcb->LBlockSize, MEM_FE_TAG);
2109 if(!(FileInfo->Dloc->FileEntry)) return STATUS_INSUFFICIENT_RESOURCES;
2110 if(!OS_SUCCESS(status = UDFReadFileEntry(Vcb, &(FileInfo->FileIdent->icb), (PFILE_ENTRY)(FileInfo->Dloc->FileEntry), &Ident)))
2111 return status;
2112 // build mappings for Data & AllocDescs
2113 if(!FileInfo->Dloc->AllocLoc.Mapping) {
2114 FEExt.extLength = FileInfo->FileIdent->icb.extLength;
2115 FEExt.extLocation = UDFPartLbaToPhys(Vcb, &(FileInfo->FileIdent->icb.extLocation) );
2116 if(FEExt.extLocation == LBA_OUT_OF_EXTENT)
2118 FileInfo->Dloc->AllocLoc.Mapping = UDFExtentToMapping(&FEExt);
2119 if(!(FileInfo->Dloc->AllocLoc.Mapping))
2121 }
2122 // read location info
2123 status = UDFLoadExtInfo(Vcb, (PFILE_ENTRY)(FileInfo->Dloc->FileEntry), &(FileInfo->FileIdent->icb),
2124 &(FileInfo->Dloc->DataLoc), &(FileInfo->Dloc->AllocLoc) );
2125 if(!OS_SUCCESS(status))
2126 return status;
2127 // init (Ex)FileEntry mapping
2128 FileInfo->Dloc->FELoc.Length = (FileInfo->Dloc->DataLoc.Offset) ? FileInfo->Dloc->DataLoc.Offset :
2129 FileInfo->Dloc->AllocLoc.Offset;
2130// FileInfo->Dloc->FELoc.Offset = 0;
2131 FileInfo->Dloc->FELoc.Mapping = UDFExtentToMapping(&FEExt);
2132 FileInfo->Dloc->FileEntryLen = (uint32)(FileInfo->Dloc->FELoc.Length);
2133 // we get here immediately when opened link encountered
2134init_tree_entry:
2135 // init back pointer from parent object
2136 ASSERT(!DirNdx->FileInfo);
2137 DirNdx->FileInfo = FileInfo;
2138 // init DirIndex
2139 if(UDFGetFileLinkCount(FileInfo) > 1) {
2140 DirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
2141 } else {
2142 DirNdx->FI_Flags &= ~UDF_FI_FLAG_LINKED;
2143 }
2144 // resize FE cache (0x800 instead of 0x40 is not a good idea)
2145 if(!MyReallocPool__((int8*)((FileInfo->Dloc->FileEntry)), Vcb->LBlockSize,
2146 (int8**)&((FileInfo->Dloc->FileEntry)), FileInfo->Dloc->FileEntryLen))
2148 // check if this file has a SDir
2149 if((FileInfo->Dloc->FileEntry->tagIdent == TID_EXTENDED_FILE_ENTRY) &&
2150 ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->streamDirectoryICB.extLength )
2151 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_HAS_SDIR;
2152 if(!(FileInfo->FileIdent->fileCharacteristics & FILE_DIRECTORY)) {
2154 ASSERT(FileInfo->ParentFile == DirInfo);
2155 UDFReleaseDloc(Vcb, FileInfo->Dloc);
2156 return STATUS_SUCCESS;
2157 }
2158
2159 UDFCheckSpaceAllocation(Vcb, 0, FileInfo->Dloc->DataLoc.Mapping, AS_USED); // check if used
2160
2161 // build index for directories
2162 if(!FileInfo->Dloc->DirIndex) {
2164 if(!OS_SUCCESS(status))
2165 return status;
2166#ifndef UDF_READ_ONLY_BUILD
2167 if((FileInfo->Dloc->DirIndex->DelCount > Vcb->PackDirThreshold) &&
2168 !(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)) {
2170 if(!OS_SUCCESS(status))
2171 return status;
2172 }
2173#endif //UDF_READ_ONLY_BUILD
2174 }
2176 UDFReleaseDloc(Vcb, FileInfo->Dloc);
2177 ASSERT(FileInfo->ParentFile == DirInfo);
2178
2179 return status;
2180} // end UDFOpenFile__()
2181
2182
2183/*
2184 This routine inits UDF_FILE_INFO structure for root directory
2185 */
2188 IN PVCB Vcb,
2189 IN lb_addr* RootLoc,
2191 )
2192{
2193 uint32 RootLBA;
2195// uint32 PartNum = RootLoc->partitionReferenceNum;
2196 uint32 LBS = Vcb->LBlockSize;
2197 uint16 Ident;
2198 LONG_AD FELoc;
2199 EXTENT_AD FEExt;
2201
2203 RootLBA = UDFPartLbaToPhys(Vcb,RootLoc);
2204 if(RootLBA == LBA_OUT_OF_EXTENT)
2206 FELoc.extLocation = *RootLoc;
2207 FELoc.extLength = LBS;
2208 // init horizontal links
2209 FileInfo->NextLinkedFile =
2210 FileInfo->PrevLinkedFile = FileInfo;
2211 // check for opened links
2212 if(!OS_SUCCESS(status = UDFStoreDloc(Vcb, FileInfo, RootLBA)))
2213 return status;
2214 if(FileInfo->Dloc->FileEntry)
2215 goto init_tree_entry;
2216 // read (Ex)FileEntry
2217 FileInfo->Dloc->FileEntry = (tag*)MyAllocatePoolTag__(NonPagedPool, LBS, MEM_FE_TAG);
2218 if(!(FileInfo->Dloc->FileEntry)) return STATUS_INSUFFICIENT_RESOURCES;
2219
2220 if(!OS_SUCCESS(status = UDFReadFileEntry(Vcb, &FELoc, (PFILE_ENTRY)(FileInfo->Dloc->FileEntry), &Ident)))
2221 return status;
2222 // build mappings for Data & AllocDescs
2223 FEExt.extLength = LBS;
2224 FEExt.extLocation = UDFPartLbaToPhys(Vcb, &(FELoc.extLocation) );
2225 if(FEExt.extLocation == LBA_OUT_OF_EXTENT)
2227 FileInfo->Dloc->FELoc.Mapping = UDFExtentToMapping(&FEExt);
2228 if(!(FileInfo->Dloc->FELoc.Mapping)) return STATUS_INSUFFICIENT_RESOURCES;
2229 // build mappings for AllocDescs
2230 if(!FileInfo->Dloc->AllocLoc.Mapping) {
2231 FileInfo->Dloc->AllocLoc.Mapping = UDFExtentToMapping(&FEExt);
2232 if(!(FileInfo->Dloc->AllocLoc.Mapping)) return STATUS_INSUFFICIENT_RESOURCES;
2233 }
2234 if(!OS_SUCCESS(status = UDFLoadExtInfo(Vcb, (PFILE_ENTRY)(FileInfo->Dloc->FileEntry), &FELoc,
2235 &(FileInfo->Dloc->DataLoc), &(FileInfo->Dloc->AllocLoc) ) ))
2236 return status;
2237 FileInfo->Dloc->FileEntryLen = (uint32)
2238 (FileInfo->Dloc->FELoc.Length = (FileInfo->Dloc->DataLoc.Offset) ? FileInfo->Dloc->DataLoc.Offset :
2239 FileInfo->Dloc->AllocLoc.Offset);
2240init_tree_entry:
2241 // resize FE cache (0x800 instead of 0x40 is not a good idea)
2242 if(!MyReallocPool__((int8*)((FileInfo->Dloc->FileEntry)), LBS,
2243 (int8**)&((FileInfo->Dloc->FileEntry)), FileInfo->Dloc->FileEntryLen))
2245 // init DirIndex
2246 if( (FileType = ((icbtag*)((FileInfo->Dloc->FileEntry)+1))->fileType) != UDF_FILE_TYPE_DIRECTORY &&
2249 UDFReleaseDloc(Vcb, FileInfo->Dloc);
2250 return STATUS_SUCCESS;
2251 }
2252 // build index for directories
2253 if(!FileInfo->Dloc->DirIndex) {
2255 if(!OS_SUCCESS(status))
2256 return status;
2257#ifndef UDF_READ_ONLY_BUILD
2258 if((FileInfo->Dloc->DirIndex->DelCount > Vcb->PackDirThreshold) &&
2259 !(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)) {
2261 if(!OS_SUCCESS(status))
2262 return status;
2263 }
2264#endif //UDF_READ_ONLY_BUILD
2265 }
2267 UDFReleaseDloc(Vcb, FileInfo->Dloc);
2268
2269 return status;
2270} // end UDFOpenRootFile__()
2271
2272/*
2273 This routine frees all memory blocks referenced by given FileInfo
2274 */
2275uint32
2277 IN PVCB Vcb,
2279 )
2280{
2281 PUDF_DATALOC_INFO Dloc;
2282 uint32 lc = 0;
2283 BOOLEAN IsASDir;
2284 BOOLEAN KeepDloc;
2285 PDIR_INDEX_ITEM DirNdx, DirNdx2;
2286 BOOLEAN Parallel = FALSE;
2288#ifdef UDF_DBG
2289 BOOLEAN Modified = FALSE;
2290 PDIR_INDEX_HDR hDirNdx;
2291 uint_di Index;
2292 PUDF_FILE_INFO DirInfo;
2293#endif // UDF_DBG
2294
2295 if(!FileInfo) return UDF_FREE_FILEINFO;
2296
2298
2299 if(FileInfo->OpenCount || FileInfo->RefCount) {
2300 UDFPrint(("UDF: not all references are closed\n"));
2301 UDFPrint((" Skipping cleanup\n"));
2302 UDFPrint(("UDF: OpenCount = %x, RefCount = %x, LinkRefCount = %x\n",
2303 FileInfo->OpenCount,FileInfo->RefCount,FileInfo->Dloc->LinkRefCount));
2304 return UDF_FREE_NOTHING;
2305 }
2306 if(FileInfo->Fcb) {
2307 UDFPrint(("Operating System still has references to this file\n"));
2308 UDFPrint((" Skipping cleanup\n"));
2309// BrutePoint();
2310 return UDF_FREE_NOTHING;
2311 }
2312
2313 IsASDir = UDFIsAStreamDir(FileInfo);
2314
2315 if((Dloc = FileInfo->Dloc)) {
2316
2317#ifdef UDF_DBG
2318 DirInfo = FileInfo->ParentFile;
2319 if(DirInfo) {
2320 hDirNdx = DirInfo->Dloc->DirIndex;
2321 Index = FileInfo->Index;
2322 // we can't delete modified file
2323 // it should be closed & reopened (or flushed) before deletion
2324 DirNdx = UDFDirIndex(hDirNdx,Index);
2325 UDFPrint(("Cleanup Mod: %s%s%s%s%s%s\n",
2326 (Dloc->FE_Flags & UDF_FE_FLAG_FE_MODIFIED) ? "FE " : "",
2327 (Dloc->DataLoc.Modified) ? "DataLoc " : "",
2328 (Dloc->DataLoc.Flags & EXTENT_FLAG_PREALLOCATED) ? "Data-PreAlloc " : "",
2329 (Dloc->AllocLoc.Modified) ? "AllocLoc " : "",
2330 (Dloc->FELoc.Modified) ? "FELoc " : "",
2331 (DirNdx && (DirNdx->FI_Flags & UDF_FI_FLAG_FI_MODIFIED)) ? "FI " : ""
2332 ));
2333 Modified = ((Dloc->FE_Flags & UDF_FE_FLAG_FE_MODIFIED) ||
2334 Dloc->DataLoc.Modified ||
2336 Dloc->AllocLoc.Modified ||
2337 Dloc->FELoc.Modified ||
2338 (DirNdx && (DirNdx->FI_Flags & UDF_FI_FLAG_FI_MODIFIED)) );
2339 }
2340#endif // UDF_DBG
2341
2343
2344 Parallel = (ParFileInfo != NULL);
2345 Linked = (FileInfo->NextLinkedFile != FileInfo);
2346
2347// Parallel = (FileInfo->NextLinkedFile != FileInfo);
2348 ASSERT(FileInfo->NextLinkedFile);
2349// ASSERT(!Parallel);
2350 KeepDloc = (Dloc->LinkRefCount ||
2351 Dloc->CommonFcb ||
2352 Linked ) ?
2353 TRUE : FALSE;
2354
2355 if(Dloc->DirIndex) {
2356 uint_di i;
2357 for(i=2; (DirNdx = UDFDirIndex(Dloc->DirIndex,i)); i++) {
2358 if(DirNdx->FileInfo) {
2359 if(!KeepDloc) {
2360 BrutePoint();
2361 UDFPrint(("UDF: Found not cleaned up reference.\n"));
2362 UDFPrint((" Skipping cleanup (1)\n"));
2363// BrutePoint();
2364 return UDF_FREE_NOTHING;
2365 }
2366 // The file being cleaned up may have not closed Dirs
2367 // (linked Dir). In this case each of them may have
2368 // reference to FileInfo in DirIndex[1]
2369 // Here we'll check it and change for valid value if
2370 // necessary (Update Child Objects - I)
2371 if(DirNdx->FileInfo->Dloc) {
2372 // we can get here only when (Parallel == TRUE)
2373 DirNdx2 = UDFDirIndex(DirNdx->FileInfo->Dloc->DirIndex, 1);
2374 // It is enough to check DirNdx2->FileInfo only.
2375 // If one of Parallel FI's has reference (and equal)
2376 // to the FI being removed, it'll be removed from
2377 // the chain & nothing wrong will happen.
2378 if(DirNdx2 && (DirNdx2->FileInfo == FileInfo)) {
2379 if(FileInfo->PrevLinkedFile == FileInfo) {
2380 BrutePoint();
2381 DirNdx2->FileInfo = NULL;
2382 } else {
2383 DirNdx2->FileInfo = Parallel ?
2384 ParFileInfo : FileInfo->PrevLinkedFile;
2385 }
2386 ASSERT(!DirNdx2->FileInfo->RefCount);
2387 }
2388 }
2389 }
2390 }
2391 }
2392 if(Dloc->SDirInfo) {
2393 UDFPrint(("UDF: Found not cleaned up reference (SDir).\n"));
2394
2395 // (Update Child Objects - II)
2396 if(Dloc->SDirInfo->ParentFile == FileInfo) {
2397 BrutePoint();
2398 ASSERT(ParFileInfo);
2399 Dloc->SDirInfo->ParentFile = ParFileInfo;
2400 }
2401 // We should break Cleanup process if alive reference detected
2402 // and there is no possibility to store pointer in some other
2403 // place (in parallel object)
2404 if(!KeepDloc) {
2405 BrutePoint();
2406 UDFPrint((" Skipping cleanup\n"));
2407 return UDF_FREE_NOTHING;
2408 }
2409
2410 if(!UDFIsSDirDeleted(Dloc->SDirInfo) &&
2411 Dloc->SDirInfo->Dloc) {
2412 DirNdx2 = UDFDirIndex(Dloc->SDirInfo->Dloc->DirIndex, 1);
2413 if(DirNdx2 && (DirNdx2->FileInfo == FileInfo)) {
2414 DirNdx2->FileInfo =
2415 Parallel ? ParFileInfo : NULL;
2416 ASSERT(!DirNdx2->FileInfo->RefCount);
2417 }
2418 }
2419 }
2420
2421 if(!KeepDloc) {
2422
2423#ifdef UDF_DBG
2424 ASSERT(!Modified);
2425#endif
2426
2427#ifndef UDF_TRACK_ONDISK_ALLOCATION
2428 if(Dloc->DataLoc.Mapping) MyFreePool__(Dloc->DataLoc.Mapping);
2429 if(Dloc->AllocLoc.Mapping) MyFreePool__(Dloc->AllocLoc.Mapping);
2430 if(Dloc->FELoc.Mapping) MyFreePool__(Dloc->FELoc.Mapping);
2431 if(Dloc->FileEntry) {
2432 // plain file
2434 MyFreePool__(Dloc->FileEntry);
2435 Dloc->FileEntry = NULL;
2436 } else if(FileInfo->Index >= 2) {
2437 // error durring open operation
2439 }
2440#endif //UDF_TRACK_ONDISK_ALLOCATION
2441 if(FileInfo->Dloc->DirIndex) {
2442 uint_di i;
2443 for(i=2; (DirNdx = UDFDirIndex(Dloc->DirIndex,i)); i++) {
2444 ASSERT(!DirNdx->FileInfo);
2445 if(DirNdx->FName.Buffer)
2446 MyFreePool__(DirNdx->FName.Buffer);
2447 }
2448 // The only place where we can free FE_Charge extent is here
2449 UDFFlushFESpace(Vcb, Dloc);
2451 Dloc->DirIndex = NULL;
2452#ifdef UDF_TRACK_ONDISK_ALLOCATION
2454 if(FileInfo->Dloc->DirIndex) {
2455 for(i=2; DirNdx = UDFDirIndex(Dloc->DirIndex,i); i++) {
2456 ASSERT(!DirNdx->FileInfo);
2457 if(DirNdx->FName.Buffer)
2458 MyFreePool__(DirNdx->FName.Buffer);
2459 }
2461 Dloc->DirIndex = NULL;
2462 }
2463#endif //UDF_TRACK_ONDISK_ALLOCATION
2464 }
2465
2466#ifdef UDF_TRACK_ONDISK_ALLOCATION
2467 if(Dloc->AllocLoc.Mapping) MyFreePool__(Dloc->AllocLoc.Mapping);
2468 if(Dloc->FELoc.Mapping) MyFreePool__(Dloc->FELoc.Mapping);
2469 if(Dloc->FileEntry) {
2470 // plain file
2472 MyFreePool__(Dloc->FileEntry);
2473 Dloc->FileEntry = NULL;
2474 } else if(FileInfo->Index >= 2) {
2475 // error durring open operation
2477 }
2478 if(Dloc->DataLoc.Mapping) {
2479 if(lc && (lc != UDF_INVALID_LINK_COUNT)) {
2480 UDFCheckSpaceAllocation(Vcb, 0, Dloc->DataLoc.Mapping, AS_USED); // check if used
2481 } else {
2482 UDFCheckSpaceAllocation(Vcb, 0, Dloc->DataLoc.Mapping, AS_FREE); // check if free
2483 }
2485 }
2486#endif //UDF_TRACK_ONDISK_ALLOCATION
2487
2488 if(lc && (lc != UDF_INVALID_LINK_COUNT)) {
2489 UDFRemoveDloc(Vcb, Dloc);
2490 } else {
2491 UDFFreeDloc(Vcb, Dloc);
2492 }
2493 } else // KeepDloc cannot be FALSE if (Linked == TRUE)
2494 if(Linked) {
2495// BrutePoint();
2496 // Update pointers in ParentObject (if any)
2497 if(FileInfo->ParentFile->Dloc->SDirInfo == FileInfo)
2498 FileInfo->ParentFile->Dloc->SDirInfo = FileInfo->PrevLinkedFile;
2499 DirNdx = UDFDirIndex(FileInfo->Dloc->DirIndex, 0);
2500 if(DirNdx && (DirNdx->FileInfo == FileInfo))
2501 DirNdx->FileInfo = FileInfo->PrevLinkedFile;
2502 DirNdx = UDFDirIndex(FileInfo->ParentFile->Dloc->DirIndex, FileInfo->Index);
2503 if(DirNdx && (DirNdx->FileInfo == FileInfo))
2504 DirNdx->FileInfo = ParFileInfo;
2505 // remove from linked chain
2506 FileInfo->NextLinkedFile->PrevLinkedFile = FileInfo->PrevLinkedFile;
2507 FileInfo->PrevLinkedFile->NextLinkedFile = FileInfo->NextLinkedFile;
2508 // update pointer in Dloc
2509 if(FileInfo->Dloc->LinkedFileInfo == FileInfo)
2510 FileInfo->Dloc->LinkedFileInfo = FileInfo->PrevLinkedFile;
2511 }
2512 FileInfo->Dloc = NULL;
2513 } else {
2514 KeepDloc = FALSE;
2515 }
2516
2517 // Cleanup pointers in ParentObject (if any)
2518 if(IsASDir) {
2519 if(FileInfo->ParentFile->Dloc->SDirInfo == FileInfo) {
2520 ASSERT(!Linked);
2521 FileInfo->ParentFile->Dloc->SDirInfo = NULL;
2522 FileInfo->ParentFile->Dloc->FE_Flags &= ~UDF_FE_FLAG_HAS_DEL_SDIR;
2523 }
2524 } else
2525 if(FileInfo->ParentFile) {
2526 ASSERT(FileInfo->ParentFile->Dloc);
2527 DirNdx = UDFDirIndex(FileInfo->ParentFile->Dloc->DirIndex, FileInfo->Index);
2528 ASSERT(DirNdx);
2529#ifdef UDF_DBG
2530 PUDF_FILE_INFO OldFI;
2531 if(Parallel) {
2532 ASSERT(!DirNdx || !(OldFI = DirNdx->FileInfo) ||
2533 !(OldFI == FileInfo));
2534 } else {
2535 ASSERT(!DirNdx || !(OldFI = DirNdx->FileInfo) ||
2536 (OldFI == FileInfo));
2537 }
2538#endif
2539 if( DirNdx && (DirNdx->FileInfo == FileInfo) ) {
2540 if(!Parallel)
2541 DirNdx->FileInfo = NULL;
2542#ifdef UDF_DBG
2543 } else {
2544 // We can get here after incomplete Open
2545 if(!Parallel && DirNdx->FileInfo)
2546 BrutePoint();
2547#endif
2548 }
2549#ifdef UDF_DBG
2550 } else {
2551// BrutePoint();
2552#endif
2553 }
2554
2555 if(!Parallel && FileInfo->FileIdent)
2556 MyFreePool__(FileInfo->FileIdent);
2557 FileInfo->FileIdent = NULL;
2558 // Kill reference to parent object
2559 FileInfo->ParentFile = NULL;
2560 // Kill references to parallel object(s) since it has no reference to
2561 // this one now
2562 FileInfo->NextLinkedFile =
2563 FileInfo->PrevLinkedFile = FileInfo;
2564 if(FileInfo->ListPtr)
2565 FileInfo->ListPtr->FileInfo = NULL;;
2566 return KeepDloc ? UDF_FREE_FILEINFO : (UDF_FREE_FILEINFO | UDF_FREE_DLOC);
2567} // end UDFCleanUpFile__()
2568
2569#ifndef UDF_READ_ONLY_BUILD
2570/*
2571 This routine creates FileIdent record in destination directory &
2572 allocates FileEntry with in-ICB zero-sized data
2573 If it returns status != STATUS_SUCCESS caller should call UDFCleanUpFile__
2574 for returned pointer *WITHOUT* using UDFCloseFile__
2575 */
2578 IN PVCB Vcb,
2579// IN uint16 AllocMode, // short/long/ext/in-icb // always in-ICB
2581 IN PUNICODE_STRING _fn,
2582 IN uint32 ExtAttrSz,
2583 IN uint32 ImpUseLen,
2584 IN BOOLEAN Extended,
2585 IN BOOLEAN CreateNew,
2586 IN OUT PUDF_FILE_INFO DirInfo,
2587 OUT PUDF_FILE_INFO* _FileInfo
2588 )
2589{
2590 uint32 l, d;
2591 uint_di i, j;
2593 LONG_AD FEicb;
2594 UDF_DIR_SCAN_CONTEXT ScanContext;
2595 PDIR_INDEX_HDR hDirNdx = DirInfo->Dloc->DirIndex;
2596 PDIR_INDEX_ITEM DirNdx;
2597 uint32 LBS = Vcb->LBlockSize;
2599 *_FileInfo = NULL;
2600 BOOLEAN undel = FALSE;
2602// BOOLEAN PackDir = FALSE;
2603 BOOLEAN FEAllocated = FALSE;
2604
2605 ValidateFileInfo(DirInfo);
2606 *_FileInfo = NULL;
2607
2608 ASSERT(DirInfo->Dloc->FELoc.Mapping[0].extLocation);
2609 uint32 PartNum = UDFGetPartNumByPhysLba(Vcb, DirInfo->Dloc->FELoc.Mapping[0].extLocation);
2610 if(!hDirNdx) return STATUS_NOT_A_DIRECTORY;
2611 i = 0;
2612
2613 _SEH2_TRY {
2614
2615 // check if exists
2616 status = UDFFindFile(Vcb, IgnoreCase, FALSE, _fn, DirInfo, &i);
2617 DirNdx = UDFDirIndex(hDirNdx,i);
2618 if(OS_SUCCESS(status)) {
2619 // file is a Cur(Parent)Dir
2621 // file deleted
2622 if(UDFIsDeleted(DirNdx)) {
2623 j=0;
2624 if(OS_SUCCESS(UDFFindFile(Vcb, IgnoreCase, TRUE, _fn, DirInfo, &j))) {
2625 i=j;
2626 DirNdx = UDFDirIndex(hDirNdx,i);
2627 goto CreateBothFound;
2628 }
2629 // we needn't allocating new FileIdent inside Dir stream
2630 // perform 'undel'
2631 if(DirNdx->FileInfo) {
2632 // BrutePoint();
2634 if(!OS_SUCCESS(status))
2636 } else {
2637 undel = TRUE;
2638 }
2639 // BrutePoint();
2640 goto CreateUndel;
2641 }
2642CreateBothFound:
2643 // file already exists
2644 if(CreateNew) try_return (status = STATUS_ACCESS_DENIED);
2645 // try to open it
2646 BrutePoint();
2647 status = UDFOpenFile__(Vcb, IgnoreCase, TRUE, _fn, DirInfo, _FileInfo,&i);
2648 // *_FileInfo = FileInfo; // OpenFile__ has already done it, so update it...
2649 DirNdx = UDFDirIndex(hDirNdx,i);
2650 DirNdx->FI_Flags &= ~UDF_FI_FLAG_SYS_ATTR;
2651 FileInfo = *_FileInfo;
2652 if(!OS_SUCCESS(status)) {
2653 // :(( can't open....
2656 *_FileInfo = NULL;
2657 }
2658 BrutePoint();
2660 }
2661 // check if we can delete this file
2662 if(FileInfo->OpenCount || (FileInfo->RefCount > 1)) {
2663 BrutePoint();
2666 }
2667 BrutePoint();
2668 // remove DIRECTORY flag
2669 DirNdx->FileCharacteristics &= ~FILE_DIRECTORY;
2670 FileInfo->FileIdent->fileCharacteristics &= ~FILE_DIRECTORY;
2672 // truncate file size to ZERO
2674 if(!OS_SUCCESS(status)) {
2675 BrutePoint();
2677 }
2678 // set NORMAL flag
2679 FileInfo->FileIdent->fileCharacteristics = 0;
2680 DirNdx->FileCharacteristics = 0;
2681 // update DeletedFiles counter in Directory... (for PackDir)
2682 if(undel && OS_SUCCESS(status))
2683 hDirNdx->DelCount--;
2685 }
2686
2687CreateUndel:
2688
2689 // allocate FileInfo
2691 *_FileInfo = FileInfo;
2692 if(!FileInfo)
2694 ImpUseLen = (ImpUseLen + 3) & ~((uint16)3);
2695
2697 // init horizontal links
2698 FileInfo->NextLinkedFile =
2699 FileInfo->PrevLinkedFile = FileInfo;
2700 // allocate space for FileEntry
2701 if(!OS_SUCCESS(status =
2702 UDFBuildFileEntry(Vcb, DirInfo, FileInfo, PartNum, ICB_FLAG_AD_IN_ICB, ExtAttrSz, Extended) )) {
2703 BrutePoint();
2705 }
2706 FEAllocated = TRUE;
2707 FEicb.extLength = LBS;
2708 ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
2709 FEicb.extLocation.logicalBlockNum = UDFPhysLbaToPart(Vcb, PartNum, FileInfo->Dloc->FELoc.Mapping[0].extLocation);
2710 FEicb.extLocation.partitionReferenceNum = (uint16)PartNum;
2711 RtlZeroMemory(&(FEicb.impUse), sizeof(FEicb.impUse));
2712
2713 if(!undel) {
2714 // build FileIdent
2715 if(!OS_SUCCESS(status =
2716 UDFBuildFileIdent(Vcb, _fn, &FEicb, ImpUseLen,
2717 &(FileInfo->FileIdent), &(FileInfo->FileIdentLen)) ))
2719 } else {
2720 // read FileIdent
2723 FileInfo->FileIdentLen = DirNdx->Length;
2724 if(!OS_SUCCESS(status = UDFReadExtent(Vcb, &(DirInfo->Dloc->DataLoc), DirNdx->Offset,
2725 DirNdx->Length, FALSE, (int8*)(FileInfo->FileIdent), &ReadBytes) ))
2727 FileInfo->FileIdent->fileCharacteristics = 0;
2728 FileInfo->FileIdent->icb = FEicb;
2729 ImpUseLen = FileInfo->FileIdent->lengthOfImpUse;
2730 DirNdx->FileCharacteristics = 0;
2731 }
2732 // init 'parentICBLocation' & so on in FE
2733 ((icbtag*)(FileInfo->Dloc->FileEntry+1))->parentICBLocation.logicalBlockNum =
2734 UDFPhysLbaToPart(Vcb, PartNum, DirInfo->Dloc->FELoc.Mapping[0].extLocation);
2735 ((icbtag*)(FileInfo->Dloc->FileEntry+1))->parentICBLocation.partitionReferenceNum = (uint16)PartNum;
2736 // ((icbtag*)(FileInfo->Dloc->FileEntry+1))->strategyType = 4;
2737 // ((icbtag*)(FileInfo->Dloc->FileEntry+1))->numEntries = 1;
2738 // try to find suitable unused FileIdent in DirIndex
2739 l = FileInfo->FileIdentLen;
2740 if(undel) goto CrF__2;
2741#ifndef UDF_LIMIT_DIR_SIZE
2742 if(Vcb->CDR_Mode) {
2743#endif // UDF_LIMIT_DIR_SIZE
2744 // search for suitable unused entry
2745 if(UDFDirIndexInitScan(DirInfo, &ScanContext, 2)) {
2746 while((DirNdx = UDFDirIndexScan(&ScanContext, NULL))) {
2747 if((DirNdx->Length == l) && UDFIsDeleted(DirNdx) &&
2748 !DirNdx->FileInfo ) {
2749 // free unicode-buffer with old name
2750 if(DirNdx->FName.Buffer) {
2751 MyFreePool__(DirNdx->FName.Buffer);
2752 DirNdx->FName.Buffer = NULL;
2753 }
2754 i = ScanContext.i;
2755 goto CrF__1;
2756 }
2757 }
2758 }
2759#ifndef UDF_LIMIT_DIR_SIZE
2760 } else {
2761#endif // UDF_LIMIT_DIR_SIZE
2762 i = UDFDirIndexGetLastIndex(hDirNdx); // 'i' points beyond EO DirIndex
2763#ifndef UDF_LIMIT_DIR_SIZE
2764 }
2765#endif // UDF_LIMIT_DIR_SIZE
2766
2767 // append entry
2768 if(!OS_SUCCESS(status = UDFDirIndexGrow(&(DirInfo->Dloc->DirIndex), 1))) {
2770 }
2771
2772 // init offset of new FileIdent in directory Data extent
2773 hDirNdx = DirInfo->Dloc->DirIndex;
2774 if(i-1) {
2775 DirNdx = UDFDirIndex(hDirNdx,i-1);
2776 UDFDirIndex(hDirNdx,i)->Offset = DirNdx->Offset + DirNdx->Length;
2777 DirNdx = UDFDirIndex(hDirNdx,i);
2778 } else {
2779 DirNdx = UDFDirIndex(hDirNdx,i);
2780 DirNdx->Offset = 0;
2781 }
2782 // new terminator is recorded by UDFDirIndexGrow()
2783 if( ((d = ((LBS - (DirNdx->Offset + l + DirInfo->Dloc->DataLoc.Offset)) & (LBS-1) )) < sizeof(FILE_IDENT_DESC)) &&
2784 d ) {
2785 // insufficient space at the end of last sector for
2786 // next FileIdent's tag. fill it with ImpUse data
2787
2788 // generally, all data should be DWORD-aligned, but if it is not so
2789 // this opearation will help us to avoid glitches
2790 d = (d+3) & ~((uint32)3);
2791
2792 uint32 IUl, FIl;
2793 if(!MyReallocPool__((int8*)(FileInfo->FileIdent), l,
2794 (int8**)&(FileInfo->FileIdent), (l+d+3) & ~((uint32)(3)) ))
2796 l += d;
2797 IUl = FileInfo->FileIdent->lengthOfImpUse;
2798 FIl = FileInfo->FileIdent->lengthFileIdent;
2799 // move filename to higher addr
2800 RtlMoveMemory(((int8*)(FileInfo->FileIdent+1))+IUl+d,
2801 ((int8*)(FileInfo->FileIdent+1))+IUl, FIl);
2802 RtlZeroMemory(((int8*)(FileInfo->FileIdent+1))+IUl, d);
2803 FileInfo->FileIdent->lengthOfImpUse += (uint16)d;
2804 FileInfo->FileIdentLen = l;
2805 }
2806 DirNdx->Length = l;
2807CrF__1:
2808 // clone unicode string
2809 // it **<<MUST>>** be allocated with internal memory manager
2810 DirNdx->FName.Buffer = (PWCHAR)MyAllocatePoolTag__(UDF_FILENAME_MT, (DirNdx->FName.MaximumLength = _fn->Length + sizeof(WCHAR)), MEM_FNAMECPY_TAG);
2811 DirNdx->FName.Length = _fn->Length;
2812 if(!DirNdx->FName.Buffer)
2814 RtlCopyMemory(DirNdx->FName.Buffer, _fn->Buffer, _fn->Length);
2815 DirNdx->FName.Buffer[_fn->Length/sizeof(WCHAR)] = 0;
2816CrF__2:
2817 DirNdx->FI_Flags |= UDFBuildHashEntry(Vcb, &(DirNdx->FName), &(DirNdx->hashes), HASH_ALL);
2818 // we get here immediately when 'undel' occured
2819 FileInfo->Index = i;
2821 DirNdx->FI_Flags &= ~UDF_FI_FLAG_SYS_ATTR;
2822 ASSERT(!DirNdx->FileInfo);
2823 DirNdx->FileInfo = FileInfo;
2824 DirNdx->FileEntryLoc = FEicb.extLocation;
2825 // mark file as 'deleted' for now
2827 FileInfo->FileIdent->fileCharacteristics |= FILE_DELETED;
2828 FileInfo->Dloc->DataLoc.Mapping = UDFExtentToMapping(&(FileInfo->Dloc->FELoc.Mapping[0]));
2829 if(!(FileInfo->Dloc->DataLoc.Mapping)) {
2830 UDFFlushFI(Vcb, FileInfo, PartNum);
2832 }
2833 FileInfo->Dloc->DataLoc.Length = 0;
2834 FileInfo->Dloc->DataLoc.Offset = FileInfo->Dloc->FileEntryLen;
2835 FileInfo->ParentFile = DirInfo;
2836 // init FileEntry
2839 UDFIncFileLinkCount(FileInfo); // increase to 1
2840 UDFUpdateCreateTime(Vcb, FileInfo);
2842 FileInfo->Dloc->FileEntry, Vcb->DefaultAttr);
2843 FileInfo->Dloc->DataLoc.Mapping[0].extLength &= UDF_EXTENT_LENGTH_MASK;
2844 FileInfo->Dloc->DataLoc.Modified = TRUE;
2845 FileInfo->Dloc->FELoc.Mapping[0].extLength &= UDF_EXTENT_LENGTH_MASK;
2846 // zero sector for FileEntry
2847 if(!Vcb->CDR_Mode) {
2848 status = UDFWriteData(Vcb, TRUE, ((int64)(FileInfo->Dloc->FELoc.Mapping[0].extLocation)) << Vcb->BlockSizeBits, LBS, FALSE, Vcb->ZBuffer, &ReadBytes);
2849 if(!OS_SUCCESS(status)) {
2850 UDFFlushFI(Vcb, FileInfo, PartNum);
2852 }
2853 }
2854#if 0
2855 if((i >= 2) && (DirNdx->FName.Buffer[0] == L'.')) {
2856 BrutePoint();
2857 }
2858#endif
2859
2860#ifdef UDF_CHECK_DISK_ALLOCATION
2861 if( /*FileInfo->Fcb &&*/
2862 UDFGetFreeBit(((uint32*)(Vcb->FSBM_Bitmap)), FileInfo->Dloc->FELoc.Mapping[0].extLocation)) {
2863
2864 if(!FileInfo->FileIdent ||
2865 !(FileInfo->FileIdent->fileCharacteristics & FILE_DELETED)) {
2866 AdPrint(("Flushing to Discarded block %x\n", FileInfo->Dloc->FELoc.Mapping[0].extLocation));
2867 BrutePoint();
2868 }
2869 }
2870#endif // UDF_CHECK_DISK_ALLOCATION
2871
2872 // make FileIdent valid
2873 FileInfo->FileIdent->fileCharacteristics = 0;
2874 DirNdx->FileCharacteristics = 0;
2876 UDFFlushFE(Vcb, FileInfo, PartNum);
2877 if(undel)
2878 hDirNdx->DelCount--;
2879 UDFReleaseDloc(Vcb, FileInfo->Dloc);
2881
2882 UDFCheckSpaceAllocation(Vcb, 0, FileInfo->Dloc->DataLoc.Mapping, AS_USED); // check if used
2883
2885
2886try_exit: NOTHING;
2887
2888 } _SEH2_FINALLY {
2889 if(!OS_SUCCESS(status)) {
2890 if(FEAllocated)
2891 UDFFreeFESpace(Vcb, DirInfo, &(FileInfo->Dloc->FELoc));
2892 }
2893 } _SEH2_END
2894 return status;
2895
2896} // end UDFCreateFile__()
2897#endif //UDF_READ_ONLY_BUILD
2898
2899/*
2900 This routine reads data from file described by FileInfo
2901 */
2902/*__inline
2903OSSTATUS
2904UDFReadFile__(
2905 IN PVCB Vcb,
2906 IN PUDF_FILE_INFO FileInfo,
2907 IN int64 Offset, // offset in extent
2908 IN SIZE_T Length,
2909 IN BOOLEAN Direct,
2910 OUT int8* Buffer,
2911 OUT PSIZE_T ReadBytes
2912 )
2913{
2914 ValidateFileInfo(FileInfo);
2915
2916 return UDFReadExtent(Vcb, &(FileInfo->Dloc->DataLoc), Offset, Length, Direct, Buffer, ReadBytes);
2917} // end UDFReadFile__()*/
2918
2919#ifndef UDF_READ_ONLY_BUILD
2920/*
2921 This routine zeros data in file described by FileInfo
2922 */
2923__inline
2926 IN PVCB Vcb,
2928 IN int64 Offset, // offset in extent
2930 IN BOOLEAN Direct,
2932 )
2933{
2935
2936 return UDFZeroExtent__(Vcb, &(FileInfo->Dloc->DataLoc), Offset, Length, Direct, ReadBytes);
2937} // end UDFZeroFile__()*/
2938
2939/*
2940 This routine makes sparse area in file described by FileInfo
2941 */
2942__inline
2945 IN PVCB Vcb,
2947 IN int64 Offset, // offset in extent
2949 IN BOOLEAN Direct,
2951 )
2952{
2954
2955 return UDFSparseExtent__(Vcb, &(FileInfo->Dloc->DataLoc), Offset, Length, Direct, ReadBytes);
2956} // end UDFSparseFile__()*/
2957
2958/*
2959 This routine fills tails of the last sector in extent with ZEROs
2960 */
2963 IN PVCB Vcb,
2964 IN PEXTENT_INFO ExtInfo
2965 )
2966{
2967 if(!ExtInfo || !(ExtInfo->Mapping) || !(ExtInfo->Length)) return STATUS_INVALID_PARAMETER;
2968
2969 PEXTENT_MAP Extent = ExtInfo->Mapping; // Extent array
2970 SIZE_T to_write, WrittenBytes;
2971 uint32 Lba, sect_offs, flags;
2973 // Length should not be zero
2974 int64 Offset = ExtInfo->Length + ExtInfo->Offset;
2975 // data is sector-size-aligned, we needn't any padding
2976 if(Offset && !((uint32)Offset & (Vcb->LBlockSize-1) )) return STATUS_SUCCESS;
2977 // get Lba of the last sector
2978 Lba = UDFExtentOffsetToLba(Vcb, Extent, Offset, &sect_offs, &to_write, &flags, NULL);
2979 // EOF check. If we have valid ExtInfo this will not happen, but who knows..
2980 if((Lba == (uint32)-1) ||
2982 return STATUS_END_OF_FILE;
2983 // write tail
2984 status = UDFWriteData(Vcb, TRUE, (((int64)Lba) << Vcb->BlockSizeBits) + sect_offs, to_write, FALSE, Vcb->ZBuffer, &WrittenBytes);
2985 return status;
2986} // UDFPadLastSector()
2987#endif //UDF_READ_ONLY_BUILD
2988
2989/*
2990 This routine updates AllocDesc sequence, FileIdent & FileEntry
2991 for given file
2992 */
2995 IN PVCB Vcb,
2997 )
2998{
3000
3001 if(!FileInfo) return STATUS_SUCCESS;
3002 if(FileInfo->Index<2 && (FileInfo->ParentFile) && !UDFIsAStreamDir(FileInfo)) {
3003 UDFPrint(("Closing Current or Parent Directory... :-\\\n"));
3004 if(FileInfo->RefCount) {
3005 UDFInterlockedDecrement((PLONG)&(FileInfo->RefCount));
3006 ASSERT(FileInfo->Dloc);
3007 if(FileInfo->Dloc)
3008 UDFInterlockedDecrement((PLONG)&(FileInfo->Dloc->LinkRefCount));
3009#ifdef UDF_DBG
3010 } else {
3011 BrutePoint();
3012 UDFPrint(("ERROR: Closing unreferenced file!\n"));
3013#endif // UDF_DBG
3014 }
3015 if(FileInfo->ParentFile->OpenCount) {
3016 UDFInterlockedDecrement((PLONG)&(FileInfo->ParentFile->OpenCount));
3017#ifdef UDF_DBG
3018 } else {
3019 BrutePoint();
3020 UDFPrint(("ERROR: Closing unopened file!\n"));
3021#endif // UDF_DBG
3022 }
3023 return STATUS_SUCCESS;
3024 }
3025 PUDF_FILE_INFO DirInfo = FileInfo->ParentFile;
3027 uint32 PartNum;
3028 if(FileInfo->RefCount) {
3029 UDFInterlockedDecrement((PLONG)&(FileInfo->RefCount));
3030 ASSERT(FileInfo->Dloc);
3031 if(FileInfo->Dloc)
3032 UDFInterlockedDecrement((PLONG)&(FileInfo->Dloc->LinkRefCount));
3033#ifdef UDF_DBG
3034 } else {
3035 BrutePoint();
3036 UDFPrint(("ERROR: Closing unreferenced file!\n"));
3037#endif // UDF_DBG
3038 }
3039 if(DirInfo) {
3040 // validate DirInfo
3041 ValidateFileInfo(DirInfo);
3042
3043 if(DirInfo->OpenCount) {
3045#ifdef UDF_DBG
3046 } else {
3047 BrutePoint();
3048 UDFPrint(("ERROR: Closing unopened file!\n"));
3049#endif // UDF_DBG
3050 }
3051 }
3052 // If the file has gone (unlinked) we should return STATUS_SUCCESS here.
3053 if(!FileInfo->Dloc) return STATUS_SUCCESS;
3054
3055 if(FileInfo->RefCount ||
3056 FileInfo->OpenCount ||
3057 !(FileInfo->Dloc->FELoc.Mapping)) return STATUS_SUCCESS;
3058// ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3059 PartNum = UDFGetPartNumByPhysLba(Vcb, FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3060 if(PartNum == (uint32)-1) {
3061 UDFPrint((" Is DELETED ?\n"));
3062 if(DirInfo) {
3063 PartNum = UDFGetPartNumByPhysLba(Vcb, DirInfo->Dloc->FELoc.Mapping[0].extLocation);
3064 } else {
3065 BrutePoint();
3066 }
3067 }
3068#ifdef UDF_CHECK_DISK_ALLOCATION
3069 if( FileInfo->Fcb &&
3070 UDFGetFreeBit(((uint32*)(Vcb->FSBM_Bitmap)), FileInfo->Dloc->FELoc.Mapping[0].extLocation)) {
3071
3072 //ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3075 UDFPrint((" Not DELETED SDir\n"));
3076 BrutePoint();
3077 }
3078 ASSERT(!FileInfo->Dloc->FELoc.Modified);
3079 } else
3080 if(!FileInfo->FileIdent ||
3081 !(FileInfo->FileIdent->fileCharacteristics & FILE_DELETED)) {
3082 if(!FileInfo->FileIdent) {
3083 AdPrint((" No FileIdent\n"));
3084 }
3085 if(FileInfo->FileIdent &&
3086 !(FileInfo->FileIdent->fileCharacteristics & FILE_DELETED))
3087 AdPrint((" Not DELETED\n"));
3088 ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3089 AdPrint(("Flushing to Discarded block %x\n", FileInfo->Dloc->FELoc.Mapping[0].extLocation));
3090 BrutePoint();
3091 } else {
3092 UDFCheckSpaceAllocation(Vcb, 0, FileInfo->Dloc->DataLoc.Mapping, AS_FREE); // check if free
3093 UDFCheckSpaceAllocation(Vcb, 0, FileInfo->Dloc->FELoc.Mapping, AS_FREE); // check if free
3094 }
3095 } else {
3096 if(!FileInfo->Dloc->FELoc.Mapping[0].extLocation ||
3097 UDFGetFreeBit(((uint32*)(Vcb->FSBM_Bitmap)), FileInfo->Dloc->FELoc.Mapping[0].extLocation)) {
3098 UDFCheckSpaceAllocation(Vcb, 0, FileInfo->Dloc->DataLoc.Mapping, AS_FREE); // check if free
3099 } else {
3100 UDFCheckSpaceAllocation(Vcb, 0, FileInfo->Dloc->DataLoc.Mapping, AS_USED); // check if used
3101 }
3102 }
3103#endif // UDF_CHECK_DISK_ALLOCATION
3104 // check if we should update parentICBLocation
3105 if( !((icbtag*)(FileInfo->Dloc->FileEntry+1))->parentICBLocation.logicalBlockNum &&
3106 !((icbtag*)(FileInfo->Dloc->FileEntry+1))->parentICBLocation.partitionReferenceNum &&
3107 DirInfo &&
3108 !Vcb->CDR_Mode &&
3109 Vcb->Modified &&
3111 ASSERT(DirInfo->Dloc->FELoc.Mapping[0].extLocation);
3112 ((icbtag*)(FileInfo->Dloc->FileEntry+1))->parentICBLocation.logicalBlockNum =
3113 UDFPhysLbaToPart(Vcb, PartNum, DirInfo->Dloc->FELoc.Mapping[0].extLocation);
3114 ((icbtag*)(FileInfo->Dloc->FileEntry+1))->parentICBLocation.partitionReferenceNum = (uint16)PartNum;
3115 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
3116 }
3117
3118 // we needn't flushing FE & Allocs untill all links are closed...
3119 if(!FileInfo->Dloc->LinkRefCount) {
3120
3121 // flush FE and pre-allocation charge for directories
3122 if(FileInfo->Dloc &&
3123 FileInfo->Dloc->DirIndex) {
3124
3126 if(FileInfo->Dloc->DataLoc.Flags & EXTENT_FLAG_PREALLOCATED) {
3127 FileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_CUT_PREALLOCATED;
3128 status = UDFResizeExtent(Vcb, PartNum, UDFGetFileSize(FileInfo), FALSE, &(FileInfo->Dloc->DataLoc));
3130 if(OS_SUCCESS(status)) {
3131 AdPrint(("Dir pre-alloc truncated (Close)\n"));
3132 FileInfo->Dloc->DataLoc.Modified = TRUE;
3133 }
3134 }
3135 }
3136
3137 if(!OS_SUCCESS(status = UDFFlushFE(Vcb, FileInfo, PartNum))) {
3138 UDFPrint(("Error flushing FE\n"));
3139//flush_recovery:
3140 BrutePoint();
3141 if(FileInfo->Index >= 2) {
3142 PDIR_INDEX_ITEM DirNdx;
3144 if(DirNdx) {
3145 UDFPrint(("Recovery: mark as deleted & flush FI\n"));
3148 FileInfo->FileIdent->fileCharacteristics |= FILE_DELETED;
3149 UDFFlushFI(Vcb, FileInfo, PartNum);
3150 }
3151 }
3152 return status;
3153 }
3154 }
3155 // ... but FI must be updated (if any)
3156 if(!OS_SUCCESS(status = UDFFlushFI(Vcb, FileInfo, PartNum))) {
3157 UDFPrint(("Error flushing FI\n"));
3158 return status;
3159 }
3160#ifdef UDF_DBG
3161// ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3162 if((FileInfo->Dloc->FileEntry->descVersion != 2) &&
3163 (FileInfo->Dloc->FileEntry->descVersion != 3)) {
3164 ASSERT(UDFGetFreeBit(((uint32*)(Vcb->FSBM_Bitmap)), FileInfo->Dloc->FELoc.Mapping[0].extLocation));
3165 }
3166#endif // UDF_DBG
3167 return STATUS_SUCCESS;
3168} // end UDFCloseFile__()
3169
3170
3171#ifndef UDF_READ_ONLY_BUILD
3172/*
3173 This routine moves file from DirInfo1 to DirInfo2 & renames it to fn
3174 */
3177 IN PVCB Vcb,
3179 IN OUT BOOLEAN* Replace, // replace if destination file exists
3180 IN PUNICODE_STRING fn, // destination
3181 IN OUT PUDF_FILE_INFO DirInfo1,
3182 IN OUT PUDF_FILE_INFO DirInfo2,
3183 IN OUT PUDF_FILE_INFO FileInfo // source (opened)
3184 )
3185{
3186 PUDF_FILE_INFO FileInfo2;
3188 PDIR_INDEX_ITEM DirNdx1;
3189 PDIR_INDEX_ITEM DirNdx2;
3190 uint_di i,j;
3191 BOOLEAN Recovery = FALSE;
3192 BOOLEAN SameFE = FALSE;
3193 uint32 NTAttr = 0;
3194
3195 // validate FileInfo
3196 ValidateFileInfo(DirInfo1);
3197 ValidateFileInfo(DirInfo2);
3199
3200 i = j = 0;
3201 if(DirInfo1 == DirInfo2) {
3202 if(OS_SUCCESS(status = UDFFindFile(Vcb, IgnoreCase, TRUE, fn, DirInfo2, &j)) &&
3203 (j==FileInfo->Index) ) {
3204 // case-only rename
3205 uint8* CS0;
3206 SIZE_T Nlen, /* l, FIXME ReactOS */ IUl;
3207
3208 // prepare filename
3209 UDFCompressUnicode(fn, &CS0, &Nlen);
3210 if(!CS0) return STATUS_INSUFFICIENT_RESOURCES;
3211/* if(Nlen > UDF_NAME_LEN) {
3212 if(CS0) MyFreePool__(CS0);
3213 return STATUS_OBJECT_NAME_INVALID;
3214 }*/
3215 // allocate memory for FI
3216 DirNdx2 = UDFDirIndex(DirInfo2->Dloc->DirIndex,j);
3217 IUl = DirNdx2->FileInfo->FileIdent->lengthOfImpUse;
3218#if 0
3219 l = (sizeof(FILE_IDENT_DESC) + Nlen + IUl + 3) & ~((uint32)3);
3220#endif
3221
3222 RtlCopyMemory( ((uint8*)(DirNdx2->FileInfo->FileIdent+1))+IUl, CS0, Nlen);
3223 RtlCopyMemory(DirNdx2->FName.Buffer, fn->Buffer, fn->Length);
3224
3225 if(CS0) MyFreePool__(CS0);
3226
3228 UDFBuildHashEntry(Vcb, &(DirNdx2->FName), &(DirNdx2->hashes), HASH_ALL);
3229 return STATUS_SUCCESS;
3230/* } else
3231 if(!OS_SUCCESS(status) && (fn->Length == UDFDirIndex(DirInfo2->Dloc->DirIndex, j=FileInfo->Index)->FName.Length)) {
3232 // target file doesn't exist, but name lengthes are equal
3233 RtlCopyMemory((DirNdx1 = UDFDirIndex(DirInfo1->Dloc->DirIndex,j))->FName.Buffer, fn->Buffer, fn->Length);
3234 DirNdx1->FI_Flags |= UDF_FI_FLAG_FI_MODIFIED;
3235 UDFBuildHashEntry(Vcb, &(DirNdx1->FName), &(DirNdx1->hashes), HASH_ALL);
3236 return STATUS_SUCCESS;*/
3237 }
3238 }
3239
3240 // PHASE 0
3241 // try to create new FileIdent & FileEntry in Dir2
3242
3243RenameRetry:
3245 0, (FileInfo->Dloc->FileEntry->tagIdent == TID_EXTENDED_FILE_ENTRY),
3246 TRUE, DirInfo2, &FileInfo2))) {
3247 UDFCleanUpFile__(Vcb, FileInfo2);
3248 if(FileInfo2) MyFreePool__(FileInfo2);
3250 // try to recover >;->
3251 if((*Replace) && !Recovery) {
3252 Recovery = TRUE;
3253 status = UDFOpenFile__(Vcb, IgnoreCase, TRUE, fn, DirInfo2, &FileInfo2, NULL);
3254 if(OS_SUCCESS(status)) {
3256 if(!OS_SUCCESS(status)) {
3257 UDFCloseFile__(Vcb, FileInfo2);
3258 goto cleanup_and_abort_rename;
3259 }
3260 status = UDFUnlinkFile__(Vcb, FileInfo2, TRUE);
3261// UDFPretendFileDeleted__(Vcb, FileInfo2);
3262 UDFCloseFile__(Vcb, FileInfo2);
3263 if(UDFCleanUpFile__(Vcb, FileInfo2)) {
3264 MyFreePool__(FileInfo2);
3265 FileInfo2 = NULL;
3266 if(SameFE)
3267 return status;
3268 } else {
3269 // we get here if the FileInfo has associated
3270 // system-specific Fcb
3271 // Such fact means that not all system references
3272 // has already gone (except Linked file case)
3273/* if(SameFE)
3274 return status;*/
3275// UDFRemoveOSReferences__(FileInfo2);
3276 if(!OS_SUCCESS(status) ||
3277 (UDFGetFileLinkCount(FileInfo2) < 1))
3279 }
3280 if(OS_SUCCESS(status)) goto RenameRetry;
3281 }
3282cleanup_and_abort_rename:
3283 if(FileInfo2 && UDFCleanUpFile__(Vcb, FileInfo2)) {
3284 MyFreePool__(FileInfo2);
3285 FileInfo2 = NULL;
3286 }
3287 } else {
3289 }
3290 }
3291 return status;
3292 }
3293 // update pointers
3294 DirNdx1 = UDFDirIndex(DirInfo1->Dloc->DirIndex, i = FileInfo->Index);
3295 DirNdx2 = UDFDirIndex(DirInfo2->Dloc->DirIndex, j = FileInfo2->Index);
3296
3297 // copy file attributes to newly created FileIdent
3298 NTAttr = UDFAttributesToNT(DirNdx1, FileInfo->Dloc->FileEntry);
3299 FileInfo2->FileIdent->fileVersionNum = FileInfo->FileIdent->fileVersionNum;
3300 // unlink source FileIdent
3302 // kill newly created entry
3303 UDFFlushFile__(Vcb, FileInfo2);
3304 UDFUnlinkFile__(Vcb, FileInfo2, TRUE);
3305 UDFCloseFile__(Vcb, FileInfo2);
3306 UDFCleanUpFile__(Vcb, FileInfo2);
3307 MyFreePool__(FileInfo2);
3308 return status;
3309 }
3310
3311 // PHASE 1
3312 // drop all unnecessary info from FileInfo & flush FI
3313
3314 DirNdx1->FileInfo = NULL;
3315 ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3316 UDFFlushFI(Vcb, FileInfo, UDFGetPartNumByPhysLba(Vcb, FileInfo->Dloc->FELoc.Mapping[0].extLocation));
3317 UDFInterlockedExchangeAdd((PLONG)&(DirInfo1->OpenCount),
3318 -((LONG)(FileInfo->RefCount)));
3319 // PHASE 2
3320 // copy all necessary info from FileInfo to FileInfo2
3321
3322 FileInfo2->FileIdent->icb = FileInfo->FileIdent->icb;
3323 FileInfo2->FileIdent->fileCharacteristics = FileInfo->FileIdent->fileCharacteristics;
3324 FileInfo2->FileIdent->fileVersionNum = FileInfo->FileIdent->fileVersionNum;
3325 MyFreePool__(FileInfo->FileIdent);
3326 FileInfo->FileIdent = NULL;
3327
3328 // PHASE 3
3329 // copy all necessary info from FileInfo2 to FileInfo
3330
3331 DirNdx2->FileInfo = FileInfo;
3332 DirNdx2->FileCharacteristics = DirNdx1->FileCharacteristics & ~FILE_DELETED;
3333 DirNdx2->FileEntryLoc = DirNdx1->FileEntryLoc;
3334 DirNdx2->FI_Flags = (DirNdx1->FI_Flags & ~UDF_FI_FLAG_SYS_ATTR) | UDF_FI_FLAG_FI_MODIFIED;
3335 UDFInterlockedExchangeAdd((PLONG)&(DirInfo2->OpenCount),
3336 FileInfo->RefCount - FileInfo2->RefCount);
3337
3338 UDFAttributesToUDF(DirNdx2, FileInfo2->Dloc->FileEntry, NTAttr);
3339
3340 FileInfo->Index = j;
3341 FileInfo->FileIdent = FileInfo2->FileIdent;
3342 FileInfo->FileIdentLen = FileInfo2->FileIdentLen;
3343 FileInfo->ParentFile = DirInfo2;
3344 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
3345
3346 ((icbtag*)(FileInfo->Dloc->FileEntry+1))->parentICBLocation =
3347 ((icbtag*)(FileInfo2->Dloc->FileEntry+1))->parentICBLocation;
3348
3349 UDFIncFileLinkCount(FileInfo); // increase to 1
3350
3351// UDFUpdateModifyTime(Vcb, FileInfo);
3352
3353 // PHASE 4
3354 // drop all unnecessary info from FileInfo2
3355
3356 UDFFreeFESpace(Vcb, DirInfo2, &(FileInfo2->Dloc->FELoc));
3357 UDFUnlinkDloc(Vcb, FileInfo2->Dloc);
3358 UDFDecFileLinkCount(FileInfo2);
3359
3360 FileInfo2->Dloc->FE_Flags &= ~UDF_FE_FLAG_FE_MODIFIED;
3361/* MyFreePool__(FileInfo2->Dloc->FileEntry);
3362 FileInfo2->Dloc->FileEntry = NULL;*/
3363 FileInfo2->ParentFile = NULL;
3364 FileInfo2->FileIdent = NULL;
3365 FileInfo2->RefCount = 0;
3366 FileInfo2->Dloc->LinkRefCount = 0;
3367 ASSERT(FileInfo2->Dloc->DataLoc.Mapping);
3368 FileInfo2->Dloc->DataLoc.Mapping[0].extLocation = 0;
3369 FileInfo2->Dloc->DataLoc.Mapping[0].extLength = 0;
3370
3371 UDFCleanUpFile__(Vcb, FileInfo2);
3372 MyFreePool__(FileInfo2);
3373
3374 // return 'delete target' status
3375 (*Replace) = Recovery;
3376
3377 return STATUS_SUCCESS;
3378} // end UDFRenameMoveFile__()
3379
3380/*
3381 This routine transforms zero-sized file to directory
3382 */
3385 IN PVCB Vcb,
3386 IN OUT PUDF_FILE_INFO DirInfo // source (opened)
3387 )
3388{
3390 LONG_AD FEicb;
3392 UDF_DATALOC_INFO Dloc;
3393 UNICODE_STRING PName;
3394 uint32 PartNum;
3395 SIZE_T WrittenBytes;
3396 PDIR_INDEX_ITEM CurDirNdx;
3397 uint32 lba;
3398
3399 // validate DirInfo
3400 ValidateFileInfo(DirInfo);
3401 if(DirInfo->ParentFile && UDFIsAStreamDir(DirInfo->ParentFile))
3402 return STATUS_ACCESS_DENIED;
3403 // file should be empty
3404 if(UDFGetFileSize(DirInfo)) {
3405 if( DirInfo->FileIdent &&
3406 (DirInfo->FileIdent->fileCharacteristics & FILE_DIRECTORY)) return STATUS_FILE_IS_A_DIRECTORY;
3408 }
3409 if(DirInfo->Dloc->DirIndex) return STATUS_FILE_IS_A_DIRECTORY;
3410 // create empty DirIndex
3411 if(DirInfo->FileIdent) DirInfo->FileIdent->fileCharacteristics |= FILE_DIRECTORY;
3412 if((CurDirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(DirInfo),DirInfo->Index)))
3413 CurDirNdx->FileCharacteristics |= FILE_DIRECTORY;
3414 ((icbtag*)(DirInfo->Dloc->FileEntry+1))->fileType = UDF_FILE_TYPE_DIRECTORY;
3415 // init temporary FileInfo
3417 FileInfo.Dloc = &Dloc;
3418 FileInfo.Dloc->FileEntry = DirInfo->ParentFile->Dloc->FileEntry;
3419 FileInfo.Dloc->FileEntryLen = DirInfo->ParentFile->Dloc->FileEntryLen;
3420 FileInfo.Dloc->DataLoc = DirInfo->Dloc->DataLoc;
3421 FileInfo.Dloc->FELoc = DirInfo->Dloc->FELoc;
3422 FileInfo.ParentFile = DirInfo;
3423 // prepare FileIdent for 'parent Dir'
3424 lba = DirInfo->Dloc->FELoc.Mapping[0].extLocation;
3425 ASSERT(lba);
3426 PartNum = UDFGetPartNumByPhysLba(Vcb, lba);
3427 FEicb.extLength = Vcb->LBlockSize;
3429 FEicb.extLocation.partitionReferenceNum = (uint16)PartNum;
3430 RtlZeroMemory(&(FEicb.impUse), sizeof(FEicb.impUse));
3431 PName.Buffer = (PWCH)L"";
3432 PName.Length = (PName.MaximumLength = sizeof(L"")) - sizeof(WCHAR);
3433 if(!OS_SUCCESS(status =
3434 UDFBuildFileIdent(Vcb, &PName, &FEicb, 0,
3435 &(FileInfo.FileIdent), &(FileInfo.FileIdentLen)) ))
3436 return status;
3437 FileInfo.FileIdent->fileCharacteristics |= (FILE_PARENT | FILE_DIRECTORY);
3440 // init structure
3441 UDFSetUpTag(Vcb, &(FileInfo.FileIdent->descTag), (uint16)(FileInfo.FileIdentLen),
3443 FileInfo.Dloc->DataLoc.Flags |= EXTENT_FLAG_VERIFY; // for metadata
3444 // flush
3445 status = UDFWriteFile__(Vcb, DirInfo, 0, FileInfo.FileIdentLen, FALSE, (int8*)(FileInfo.FileIdent), &WrittenBytes);
3446// status = UDFFlushFI(Vcb, &FileInfo, PartNum);
3447
3448#ifdef UDF_DBG
3449 if(Vcb->CompatFlags & UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS) {
3450 ASSERT(UDFGetFileSize(DirInfo) <= UDFGetExtentLength(DirInfo->Dloc->DataLoc.Mapping));
3451 } else {
3452 ASSERT(((UDFGetFileSize(DirInfo)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)) ==
3453 ((UDFGetExtentLength(DirInfo->Dloc->DataLoc.Mapping)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)));
3454 }
3455#endif // UDF_DBG
3456
3457 MyFreePool__(FileInfo.FileIdent);
3458 if(!OS_SUCCESS(status)) return status;
3459 if(CurDirNdx) CurDirNdx->FileCharacteristics =
3460 DirInfo->FileIdent->fileCharacteristics;
3461 return UDFIndexDirectory(Vcb, DirInfo);
3462} // end UDFRecordDirectory__()
3463
3464/*
3465 This routine changes file size (on disc)
3466 */
3469 IN PVCB Vcb,
3472 )
3473{
3474 SIZE_T WrittenBytes;
3476 uint32 PartNum;
3477 int8* OldInIcb = NULL;
3478 PEXTENT_MAP NewMap;
3479
3480 UDFPrint(("UDFResizeFile__: FI %x, -> %I64x\n", FileInfo, NewLength));
3482// ASSERT(FileInfo->RefCount >= 1);
3483
3484 if((NewLength >> Vcb->LBlockSizeBits) > Vcb->TotalAllocUnits) {
3485 UDFPrint(("STATUS_DISK_FULL\n"));
3486 return STATUS_DISK_FULL;
3487 }
3488 if (NewLength == FileInfo->Dloc->DataLoc.Length) return STATUS_SUCCESS;
3489 if(FileInfo->ParentFile && (FileInfo->Index >= 2)) {
3490 UDFDirIndex(FileInfo->ParentFile->Dloc->DirIndex,FileInfo->Index)->FI_Flags &= ~UDF_FI_FLAG_SYS_ATTR;
3491 }
3492 if(NewLength > FileInfo->Dloc->DataLoc.Length) {
3493 // grow file
3494 return UDFWriteFile__(Vcb, FileInfo, NewLength, 0, FALSE, NULL, &WrittenBytes);
3495 }
3496 // truncate file
3497 if(NewLength <= (Vcb->LBlockSize - FileInfo->Dloc->FileEntryLen)) {
3498 // check if we are already in IN_ICB mode
3499 if((((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK) != ICB_FLAG_AD_IN_ICB) {
3500 // read data from old location
3501 if(NewLength) {
3503 if(!OldInIcb) return STATUS_INSUFFICIENT_RESOURCES;
3504 status = UDFReadExtent(Vcb, &(FileInfo->Dloc->DataLoc), 0, (uint32)NewLength, FALSE, OldInIcb, &WrittenBytes);
3505 if(!OS_SUCCESS(status)) {
3506 MyFreePool__(OldInIcb);
3507 return status;
3508 }
3509 } else {
3510 OldInIcb = NULL;
3511 }
3512 // allocate storage for new mapping
3515 if(!(NewMap)) {
3516 MyFreePool__(OldInIcb);
3518 }
3519 // free old location...
3520 if(FileInfo->Dloc->DataLoc.Mapping[0].extLocation !=
3521 FileInfo->Dloc->FELoc.Mapping[0].extLocation) {
3522 ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3523mark_data_map_0:
3524 UDFMarkSpaceAsXXX(Vcb, FileInfo->Dloc, FileInfo->Dloc->DataLoc.Mapping, AS_DISCARDED); // free
3525 } else {
3526 if((FileInfo->Dloc->DataLoc.Mapping[0].extLength & UDF_EXTENT_LENGTH_MASK)
3527 > Vcb->LBlockSize) {
3528 BrutePoint();
3529 FileInfo->Dloc->DataLoc.Mapping[0].extLength -= Vcb->LBlockSize;
3530 FileInfo->Dloc->DataLoc.Mapping[0].extLocation += (1 << Vcb->LB2B_Bits);
3531 goto mark_data_map_0;
3532 }
3533 UDFMarkSpaceAsXXX(Vcb, FileInfo->Dloc, &(FileInfo->Dloc->DataLoc.Mapping[1]), AS_DISCARDED); // free
3534 }
3535 if(FileInfo->Dloc->AllocLoc.Mapping) {
3536 if((FileInfo->Dloc->AllocLoc.Mapping[0].extLength & UDF_EXTENT_LENGTH_MASK)
3537 > Vcb->LBlockSize) {
3538 FileInfo->Dloc->AllocLoc.Mapping[0].extLength -= Vcb->LBlockSize;
3539 FileInfo->Dloc->AllocLoc.Mapping[0].extLocation += (1 << Vcb->LB2B_Bits);
3540 UDFMarkSpaceAsXXX(Vcb, FileInfo->Dloc, FileInfo->Dloc->AllocLoc.Mapping, AS_DISCARDED); // free
3541 } else {
3542 UDFMarkSpaceAsXXX(Vcb, FileInfo->Dloc, &(FileInfo->Dloc->AllocLoc.Mapping[1]), AS_DISCARDED); // free
3543 }
3544 MyFreePool__(FileInfo->Dloc->AllocLoc.Mapping);
3545 }
3546 MyFreePool__(FileInfo->Dloc->DataLoc.Mapping);
3547 FileInfo->Dloc->AllocLoc.Mapping = NULL;
3548 FileInfo->Dloc->AllocLoc.Length = 0;
3549 FileInfo->Dloc->AllocLoc.Offset = 0;
3550 FileInfo->Dloc->AllocLoc.Modified = TRUE;
3551 // switch to IN_ICB mode
3552 ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags &= ~ICB_FLAG_ALLOC_MASK;
3553 ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags |= ICB_FLAG_AD_IN_ICB;
3554 // init new data location descriptors
3555 FileInfo->Dloc->DataLoc.Mapping = NewMap;
3556 RtlZeroMemory((int8*)(FileInfo->Dloc->DataLoc.Mapping), 2*sizeof(EXTENT_MAP));
3557 FileInfo->Dloc->DataLoc.Mapping[0] = FileInfo->Dloc->FELoc.Mapping[0];
3558 FileInfo->Dloc->DataLoc.Length = NewLength;
3559 FileInfo->Dloc->DataLoc.Offset = FileInfo->Dloc->FileEntryLen;
3560 // write data to new location
3561 if(OldInIcb) {
3562 status = UDFWriteExtent(Vcb, &(FileInfo->Dloc->DataLoc), 0, (uint32)NewLength, FALSE, OldInIcb, &WrittenBytes);
3563 } else {
3565 }
3566 FileInfo->Dloc->DataLoc.Modified = TRUE;
3567 if(OldInIcb) MyFreePool__(OldInIcb);
3568 } else {
3569 // just modify Length field
3570 FileInfo->Dloc->DataLoc.Length = NewLength;
3572 }
3573 } else {
3574 // resize extent
3575 ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3576 PartNum = UDFGetPartNumByPhysLba(Vcb, FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3577 status = UDFResizeExtent(Vcb, PartNum, NewLength, FALSE, &(FileInfo->Dloc->DataLoc));
3578 FileInfo->Dloc->DataLoc.Modified = TRUE;
3579 FileInfo->Dloc->AllocLoc.Modified = TRUE;
3580 }
3581 if(OS_SUCCESS(status)) {
3583 }
3584
3585#ifdef UDF_DBG
3586 if(Vcb->CompatFlags & UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS) {
3587 ASSERT(UDFGetFileSize(FileInfo) <= UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping));
3588 } else {
3589 ASSERT(((UDFGetFileSize(FileInfo)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)) ==
3590 ((UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)));
3591 }
3592#endif // UDF_DBG
3593
3594 return status;
3595} // end UDFResizeFile__()
3596#endif //UDF_READ_ONLY_BUILD
3597
3598/*
3599 This routine loads VAT.
3600 */
3603 IN PVCB Vcb,
3604 IN uint32 PartNdx
3605 )
3606{
3607 lb_addr VatFELoc;
3609 PUDF_FILE_INFO VatFileInfo;
3610 uint32 len, i=0, j, to_read;
3611 uint32 Offset, hdrOffset;
3613 uint32 root;
3614 uint16 PartNum;
3615// uint32 VatFirstLba = 0;
3616 int8* VatOldData;
3617 uint32 VatLba[6] = { Vcb->LastLBA,
3618 Vcb->LastLBA - 2,
3619 Vcb->LastLBA - 3,
3620 Vcb->LastLBA - 5,
3621 Vcb->LastLBA - 7,
3622 0 };
3623
3624 if(Vcb->Vat) return STATUS_SUCCESS;
3625 if(!Vcb->CDR_Mode) return STATUS_SUCCESS;
3626 // disable VAT for now. We'll reenable it if VAT is successfuly loaded
3627 Vcb->CDR_Mode = FALSE;
3628 PartNum = Vcb->Partitions[PartNdx].PartitionNum;
3629 root = Vcb->Partitions[PartNdx].PartitionRoot;
3630 if(Vcb->LBlockSize != Vcb->BlockSize) {
3631 // don't know how to operate... :(((
3633 }
3634 if((Vcb->LastTrackNum > 1) &&
3635 (Vcb->LastLBA == Vcb->TrackMap[Vcb->LastTrackNum-1].LastLba)) {
3636 UDFPrint(("Hardware Read-only volume\n"));
3638 }
3639
3641 if(!VatFileInfo) return STATUS_INSUFFICIENT_RESOURCES;
3642 // load VAT FE (we know its location)
3643 VatFELoc.partitionReferenceNum = PartNum;
3644retry_load_vat:
3645 VatFELoc.logicalBlockNum = UDFPhysLbaToPart(Vcb, PartNum, VatLba[i]);
3646 if(!OS_SUCCESS(status = UDFOpenRootFile__(Vcb, &VatFELoc, VatFileInfo))) {
3647 UDFCleanUpFile__(Vcb, VatFileInfo);
3648 // try another location
3649 i++;
3650 if( VatLba[i] &&
3652 (status != STATUS_CRC_ERROR)) goto retry_load_vat;
3653 MyFreePool__(VatFileInfo);
3654 Vcb->VatFileInfo = NULL;
3655 return status;
3656 }
3657 len = (uint32)UDFGetFileSize(VatFileInfo);
3658 if(Vcb->Partitions[PartNdx].PartitionType == UDF_VIRTUAL_MAP15) {
3659 // load Vat 1.50 header
3660 UDFPrint(("Load VAT 1.50\n"));
3662 if(((icbtag*)(VatFileInfo->Dloc->FileEntry+1))->fileType != UDF_FILE_TYPE_VAT15) {
3664 goto err_vat_15;
3665 }
3667 if(!Buf) {
3668err_vat_15_2:
3670err_vat_15:
3671 UDFCloseFile__(Vcb, VatFileInfo);
3672 UDFCleanUpFile__(Vcb, VatFileInfo);
3673 MyFreePool__(VatFileInfo);
3674 Vcb->VatFileInfo = NULL;
3675 return status;
3676 }
3677 Offset = 0;
3678 to_read =
3679 hdrOffset = len - sizeof(VirtualAllocationTable15);
3680 MyFreePool__(Buf);
3681
3682 Vcb->minUDFReadRev =
3683 Vcb->minUDFWriteRev =
3684 Vcb->maxUDFWriteRev = 0x0150;
3685
3686 Vcb->numFiles =
3687 Vcb->numDirs = -1;
3688
3689 } else
3690 if(Vcb->Partitions[PartNdx].PartitionType == UDF_VIRTUAL_MAP20) {
3691 // load Vat 2.00 header
3692 UDFPrint(("Load VAT 2.00\n"));
3694 if(((icbtag*)(VatFileInfo->Dloc->FileEntry+1))->fileType != UDF_FILE_TYPE_VAT20) {
3696 goto err_vat_15;
3697 }
3699 if(!Buf) goto err_vat_15_2;
3700 Offset = Buf->lengthHeader;
3701 to_read = len - Offset;
3702 hdrOffset = 0;
3703 MyFreePool__(Buf);
3704
3705 Vcb->minUDFReadRev = Buf->minReadRevision;
3706 Vcb->minUDFWriteRev = Buf->minWriteRevision;
3707 Vcb->maxUDFWriteRev = Buf->maxWriteRevision;
3708
3709 Vcb->numFiles = Buf->numFIDSFiles;
3710 Vcb->numDirs = Buf->numFIDSDirectories;
3711
3712 } else {
3713 // unknown (or wrong) VAT format
3714 UDFPrint(("unknown (or wrong) VAT format\n"));
3716 goto err_vat_15;
3717 }
3718 // read VAT & remember old version
3719 Vcb->Vat = (uint32*)DbgAllocatePool(NonPagedPool, (Vcb->LastPossibleLBA+1)*sizeof(uint32) );
3720 if(!Vcb->Vat) {
3721 goto err_vat_15_2;
3722 }
3723 // store base version of VAT in memory
3724 VatOldData = (int8*)DbgAllocatePool(PagedPool, len);
3725 if(!VatOldData) {
3726 DbgFreePool(Vcb->Vat);
3727 Vcb->Vat = NULL;
3728 goto err_vat_15_2;
3729 }
3730 status = UDFReadFile__(Vcb, VatFileInfo, 0, len, FALSE, VatOldData, &ReadBytes);
3731 if(!OS_SUCCESS(status)) {
3732 UDFCloseFile__(Vcb, VatFileInfo);
3733 UDFCleanUpFile__(Vcb, VatFileInfo);
3734 MyFreePool__(VatFileInfo);
3735 DbgFreePool(Vcb->Vat);
3736 DbgFreePool(VatOldData);
3737 Vcb->Vat = NULL;
3738 Vcb->VatFileInfo = NULL;
3739 } else {
3740 // initialize VAT
3741 // !!! NOTE !!!
3742 // Both VAT copies - in-memory & on-disc
3743 // contain _relative_ addresses
3744 len = Vcb->NWA - root;
3745 for(i=0; i<=len; i++) {
3746 Vcb->Vat[i] = i;
3747 }
3748 RtlCopyMemory(Vcb->Vat, VatOldData+Offset, to_read);
3749 Vcb->InitVatCount =
3750 Vcb->VatCount = to_read/sizeof(uint32);
3751 Vcb->VatPartNdx = PartNdx;
3752 Vcb->CDR_Mode = TRUE;
3753 len = Vcb->VatCount;
3754 RtlFillMemory(&(Vcb->Vat[Vcb->NWA-root]), (Vcb->LastPossibleLBA-Vcb->NWA+1)*sizeof(uint32), 0xff);
3755 // sync VAT and FSBM
3756 for(i=0; i<len; i++) {
3757 if(Vcb->Vat[i] == UDF_VAT_FREE_ENTRY) {
3758 UDFSetFreeBit(Vcb->FSBM_Bitmap, root+i);
3759 }
3760 }
3761 len = Vcb->LastPossibleLBA;
3762 // "pre-format" reserved area
3763 for(i=Vcb->NWA; i<len;) {
3764 for(j=0; (j<PACKETSIZE_UDF) && (i<len); j++, i++)
3765 UDFSetFreeBit(Vcb->FSBM_Bitmap, i);
3766 for(j=0; (j<7) && (i<len); j++, i++)
3767 UDFSetUsedBit(Vcb->FSBM_Bitmap, i);
3768 }
3769 DbgFreePool(VatOldData);
3770 }
3771 return status;
3772} // end UDFLoadVAT()
3773
3774/*
3775 Reads Extended Attributes
3776 Caller should use UDFGetFileEALength to allocate Buffer of sufficient
3777 size
3778 *//*
3779OSSTATUS
3780UDFReadFileEA(
3781 IN PVCB Vcb,
3782 IN PDIR_INDEX FileDirNdx,
3783 OUT int8* Buffer
3784 )
3785{
3786 PFILE_ENTRY FileEntry;
3787 OSSTATUS status;
3788
3789 if(FileDirNdx->FileInfo) {
3790 FileEntry = (PFILE_ENTRY)(FileDirNdx->FileInfo->Dloc->FileEntry);
3791 } else {
3792 FileEntry = (PFILE_ENTRY)MyAllocatePool__(NonPagedPool, Vcb->BlockSize);
3793 if(!FileEntry) return;
3794 if(!OS_SUCCESS(status = UDFReadFileEntry(Vcb, &(FileDirNdx->FileEntry), FileEntry, &Ident))) {
3795 MyFreePool__(FileEntry);
3796 return status;
3797 }
3798 }
3799}*/
3800/*
3801 This dumb routine checks if the file has been found is deleted
3802 It is introduced to make main modules FS-type independent
3803 */
3804/*BOOLEAN
3805UDFIsDeleted(
3806 IN PDIR_INDEX DirNdx
3807 )
3808{
3809 return (DirNdx->FileCharacteristics & FILE_DELETED);
3810} */
3811
3812/*BOOLEAN
3813UDFIsADirectory(
3814 IN PUDF_FILE_INFO FileInfo
3815 )
3816{
3817 ValidateFileInfo(FileInfo);
3818
3819 if(!FileInfo) return FALSE;
3820 if(FileInfo->Dloc->DirIndex) return TRUE;
3821 if(!(FileInfo->FileIdent)) return FALSE;
3822 return (FileInfo->FileIdent->fileCharacteristics & FILE_DIRECTORY);
3823} */
3824/*
3825 This routine calculates actual allocation size
3826 */
3827/*int64
3828UDFGetFileAllocationSize(
3829 IN PVCB Vcb,
3830 IN PUDF_FILE_INFO FileInfo
3831 )
3832{
3833 ValidateFileInfo(FileInfo);
3834
3835 return UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping);// +
3836// UDFGetExtentLength(FileInfo->Dloc->FELoc.Mapping) +
3837// UDFGetExtentLength(FileInfo->Dloc->AllocLoc.Mapping) - Vcb->BlockSize;
3838}*/
3839
3840/*
3841 This routine checks if the directory is empty
3842 */
3843BOOLEAN
3845 IN PDIR_INDEX_HDR hCurDirNdx
3846 )
3847{
3848 uint32 fc;
3849 uint_di i;
3850 PDIR_INDEX_ITEM CurDirNdx;
3851 // not empty
3852 for(i=2; (CurDirNdx = UDFDirIndex(hCurDirNdx,i)); i++) {
3853 fc = CurDirNdx->FileCharacteristics;
3854 if(!(fc & (FILE_PARENT | FILE_DELETED)) &&
3855 CurDirNdx->Length)
3856 return FALSE;
3857 }
3858 return TRUE;
3859} // end UDFIsDirEmpty()
3860
3861/*
3862 */
3865 IN PVCB Vcb,
3867 IN uint32 PartNum
3868 )
3869{
3870 int8* NewAllocDescs;
3872 SIZE_T WrittenBytes;
3873 uint16 AllocMode;
3874 uint32 lba;
3875
3876 AllocMode = ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK;
3877#ifdef UDF_DBG
3878/* if(UDFIsADirectory(FileInfo) && (UDFGetFileSize(FileInfo) < 0x28) &&
3879 !UDFIsDeleted(UDFDirIndex(DirInfo->Dloc->DirIndex, FileInfo->Index)) ) {
3880 BrutePoint();
3881 }*/
3882// ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
3883 if(FileInfo->Dloc->FELoc.Offset) {
3884 BrutePoint();
3885 }
3886 if(FileInfo->Dloc->AllocLoc.Mapping) {
3887 ASSERT(AllocMode != ICB_FLAG_AD_IN_ICB);
3888 }
3889#endif // UDF_DBG
3890retry_flush_FE:
3891 UDFPrint((" FlushFE: %x\n", FileInfo->Dloc->FELoc.Mapping[0].extLocation));
3892#ifndef UDF_READ_ONLY_BUILD
3894 if(FileInfo->Dloc->DataLoc.Modified ||
3895 FileInfo->Dloc->AllocLoc.Modified) {
3896 ASSERT(PartNum != (uint32)(-1));
3897 // prepare new AllocDescs for flushing...
3898 if(!OS_SUCCESS(status = UDFBuildAllocDescs(Vcb, PartNum, FileInfo, &NewAllocDescs))) {
3899 UDFPrint((" FlushFE: UDFBuildAllocDescs() faliled (%x)\n", status));
3900 if(NewAllocDescs)
3901 MyFreePool__(NewAllocDescs);
3902 return status;
3903 }
3904#ifdef UDF_DBG
3905 if(Vcb->CompatFlags & UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS) {
3906 ASSERT(UDFGetFileSize(FileInfo) <= UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping));
3907 } else {
3908 ASSERT(((UDFGetFileSize(FileInfo)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)) ==
3909 ((UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)));
3910 }
3911 AllocMode = ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK;
3912#endif // UDF_DBG
3913 // initiate update of lengthAllocDescs
3914 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
3915 if(NewAllocDescs) {
3916 ASSERT(AllocMode != ICB_FLAG_AD_IN_ICB);
3917 status = UDFPadLastSector(Vcb, &(FileInfo->Dloc->AllocLoc));
3918 // ... and flush it
3919 status = UDFWriteExtent(Vcb, &(FileInfo->Dloc->AllocLoc), 0, (uint32)(FileInfo->Dloc->AllocLoc.Length), FALSE, NewAllocDescs, &WrittenBytes);
3920 MyFreePool__(NewAllocDescs);
3921 if(!OS_SUCCESS(status)) {
3922 UDFPrint((" FlushFE: UDFWriteExtent() faliled (%x)\n", status));
3923 return status;
3924 }
3925#ifdef UDF_DBG
3926 } else {
3927 ASSERT(AllocMode == ICB_FLAG_AD_IN_ICB);
3928#endif // UDF_DBG
3929 }
3930 FileInfo->Dloc->DataLoc.Modified = FALSE;
3931 FileInfo->Dloc->AllocLoc.Modified = FALSE;
3932 } else {
3933#if defined(UDF_DBG) && !defined(UDF_CHECK_UTIL)
3934 if(Vcb->CompatFlags & UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS) {
3935 ASSERT(UDFGetFileSize(FileInfo) <= UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping));
3936 } else {
3937 ASSERT(((UDFGetFileSize(FileInfo)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)) ==
3938 ((UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping)+Vcb->LBlockSize-1) & (Vcb->LBlockSize-1)));
3939 }
3940#endif // UDF_DBG
3941 }
3942/* if(FileInfo->Fcb &&
3943 ((FileInfo->Dloc->FELoc.Mapping[0].extLocation > Vcb->LastLBA) ||
3944 UDFGetFreeBit(((uint32*)(Vcb->FSBM_Bitmap)), FileInfo->Dloc->FELoc.Mapping[0].extLocation)) ) {
3945 BrutePoint();
3946 }*/
3947/* if(FileInfo->Dloc->FELoc.Mapping[0].extLocation) {
3948 ASSERT( FileInfo->Dloc->FileEntry->tagLocation ==
3949 (FileInfo->Dloc->FELoc.Mapping[0].extLocation - 0x580));
3950 }*/
3951 if((FileInfo->Dloc->FE_Flags & UDF_FE_FLAG_FE_MODIFIED) ||
3952 FileInfo->Dloc->FELoc.Modified) {
3953 ASSERT(PartNum != (uint32)(-1));
3954 ASSERT(!PartNum);
3955 if(PartNum == (uint32)(-1) || PartNum == (uint32)(-2)) {
3956 UDFPrint((" bad PartNum: %d\n", PartNum));
3957 }
3958 // update lengthAllocDescs in FE
3960/* ASSERT( FileInfo->Dloc->FileEntry->tagLocation ==
3961 (FileInfo->Dloc->FELoc.Mapping[0].extLocation - 0x580));*/
3962 // flush FileEntry
3963
3964 // if FE is located in remapped block, place it to reliable space
3965 lba = FileInfo->Dloc->FELoc.Mapping[0].extLocation;
3966 if(Vcb->BSBM_Bitmap) {
3967 if(UDFGetBadBit((uint32*)(Vcb->BSBM_Bitmap), lba)) {
3968 AdPrint((" bad block under FE @%x\n", lba));
3969 goto relocate_FE;
3970 }
3971 }
3972
3973 AdPrint((" setup tag: @%x\n", lba));
3974 ASSERT( lba );
3975 UDFSetUpTag(Vcb, FileInfo->Dloc->FileEntry, (uint16)(FileInfo->Dloc->FileEntryLen),
3976 UDFPhysLbaToPart(Vcb, PartNum, lba));
3977 status = UDFWriteExtent(Vcb, &(FileInfo->Dloc->FELoc), 0,
3978 (uint32)(FileInfo->Dloc->FELoc.Length), FALSE,
3979 (int8*)(FileInfo->Dloc->FileEntry), &WrittenBytes);
3980 if(!OS_SUCCESS(status)) {
3981 UDFPrint((" FlushFE: UDFWriteExtent(2) faliled (%x)\n", status));
3983relocate_FE:
3984 UDFPrint((" try to relocate\n"));
3985
3986 EXTENT_INFO _FEExtInfo;
3987 // calculate the length required
3988
3989 // allocate block for FE
3990 if(OS_SUCCESS(UDFAllocateFESpace(Vcb, FileInfo->ParentFile, PartNum, &_FEExtInfo, (uint32)(FileInfo->Dloc->FELoc.Length)) )) {
3991 UDFPrint((" relocate %x -> %x\n",
3992 lba,
3993 _FEExtInfo.Mapping[0].extLocation));
3994
3995 UDFMarkSpaceAsXXX(Vcb, 0, FileInfo->Dloc->FELoc.Mapping, AS_BAD);
3996
3997 UDFRelocateDloc(Vcb, FileInfo->Dloc, _FEExtInfo.Mapping[0].extLocation);
3998 MyFreePool__(FileInfo->Dloc->FELoc.Mapping);
3999 FileInfo->Dloc->FELoc.Mapping = _FEExtInfo.Mapping;
4000
4001 FileInfo->Dloc->FELoc.Modified = TRUE;
4002 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
4003
4004 AllocMode = ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK;
4005 if(AllocMode == ICB_FLAG_AD_IN_ICB) {
4006 UDFPrint((" IN-ICB data lost\n"));
4007 FileInfo->Dloc->DataLoc.Mapping[0].extLocation = _FEExtInfo.Mapping[0].extLocation;
4008 FileInfo->Dloc->DataLoc.Modified = TRUE;
4009 } else {
4010 FileInfo->Dloc->AllocLoc.Mapping[0].extLocation = _FEExtInfo.Mapping[0].extLocation;
4011 FileInfo->Dloc->AllocLoc.Modified = TRUE;
4012 }
4013
4014 if(FileInfo->Index >= 2) {
4015 PDIR_INDEX_ITEM DirNdx;
4017 if(DirNdx) {
4018 UDFPrint((" update reference in FI\n"));
4020 FileInfo->FileIdent->icb.extLocation.logicalBlockNum =
4021 UDFPhysLbaToPart(Vcb, PartNum, _FEExtInfo.Mapping[0].extLocation);
4023 }
4024 }
4025 // this will update
4026 UDFPrint((" retry flush...\n"));
4027 goto retry_flush_FE;
4028 }
4029 }
4030 BrutePoint();
4031 return status;
4032 }
4033 FileInfo->Dloc->FE_Flags &= ~UDF_FE_FLAG_FE_MODIFIED;
4034 FileInfo->Dloc->FELoc.Modified = FALSE;
4035 } else {
4036 ASSERT((FileInfo->Dloc->FileEntry->descVersion == 2) ||
4037 (FileInfo->Dloc->FileEntry->descVersion == 3));
4038 }
4039#endif //UDF_READ_ONLY_BUILD
4040#ifdef UDF_DBG
4041 if(FileInfo->Dloc->AllocLoc.Mapping) {
4042 ASSERT(AllocMode != ICB_FLAG_AD_IN_ICB);
4043 } else {
4044 ASSERT(AllocMode == ICB_FLAG_AD_IN_ICB);
4045 }
4046#endif // UDF_DBG
4047 return STATUS_SUCCESS;
4048} // end UDFFlushFE()
4049
4052 IN PVCB Vcb,
4054 IN uint32 PartNum
4055 )
4056{
4057 PUDF_FILE_INFO DirInfo = FileInfo->ParentFile;
4058 PDIR_INDEX_ITEM DirNdx;
4060 SIZE_T WrittenBytes;
4061 // use WrittenBytes variable to store LBA of FI to be recorded
4062 #define lba WrittenBytes
4063
4064// ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
4065 // some files has no FI
4066 if(!DirInfo || UDFIsAStreamDir(FileInfo))
4067 return STATUS_SUCCESS;
4068 DirNdx = UDFDirIndex(DirInfo->Dloc->DirIndex, FileInfo->Index);
4069// ASSERT(FileInfo->FileIdent->lengthFileIdent < 0x80);
4070#ifdef UDF_DBG
4071 if(DirNdx->FileCharacteristics & FILE_DELETED) {
4072 ASSERT(FileInfo->FileIdent->fileCharacteristics & FILE_DELETED);
4073 }
4074#endif // UDF_DBG
4075 UDFPrint((" FlushFI: offs %x\n", (ULONG)(DirNdx->Offset)));
4076#ifndef UDF_READ_ONLY_BUILD
4077 if((DirNdx->FI_Flags & UDF_FI_FLAG_FI_MODIFIED)) {
4078 // flush FileIdent
4079 ASSERT(PartNum != (uint32)(-1));
4080 FileInfo->FileIdent->fileCharacteristics = DirNdx->FileCharacteristics;
4082 DirNdx->Offset, NULL, NULL, NULL, NULL);
4083 AdPrint((" FI lba %x\n", lba));
4084 // check if requested Offset is allocated
4085 if(lba == (uint32)LBA_OUT_OF_EXTENT) {
4086 // write 1 byte
4087 if(!OS_SUCCESS(status = UDFWriteFile__(Vcb, DirInfo, DirNdx->Offset, 1, FALSE, (int8*)(FileInfo->FileIdent), &WrittenBytes) )) {
4088 BrutePoint();
4089 return status;
4090 }
4092 DirNdx->Offset, NULL, NULL, NULL, NULL);
4093 AdPrint((" allocated FI lba %x\n", lba));
4094 // check if requested Offset is allocated
4095 if(lba == (uint32)LBA_OUT_OF_EXTENT) {
4096 BrutePoint();
4097 return STATUS_UNSUCCESSFUL;
4098 }
4099 }
4100 // init structure
4101 UDFSetUpTag(Vcb, &(FileInfo->FileIdent->descTag), (uint16)(FileInfo->FileIdentLen),
4102 UDFPhysLbaToPart(Vcb, PartNum, lba));
4103 // record data
4104 if(!OS_SUCCESS(status = UDFWriteFile__(Vcb, DirInfo, DirNdx->Offset, FileInfo->FileIdentLen, FALSE, (int8*)(FileInfo->FileIdent), &WrittenBytes) )) {
4105 BrutePoint();
4106 return status;
4107 }
4108 DirNdx->FI_Flags &= ~UDF_FI_FLAG_FI_MODIFIED;
4109 }
4110#endif //UDF_READ_ONLY_BUILD
4111 return STATUS_SUCCESS;
4112} // end UDFFlushFI()
4113
4114/*
4115 This routine updates AllocDesc sequence, FileIdent & FileEntry
4116 for given file
4117 */
4120 IN PVCB Vcb,
4122 IN ULONG FlushFlags
4123 )
4124{
4126
4127 if(!FileInfo) return STATUS_SUCCESS;
4129 uint32 PartNum;
4130
4131 ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation);
4132 PartNum = UDFGetPartNumByPhysLba(Vcb, FileInfo->Dloc->FELoc.Mapping[0].extLocation);
4133 if(PartNum == (uint32)-1) {
4134 UDFPrint((" Is DELETED ?\n"));
4135 if(FileInfo->ParentFile) {
4136 PartNum = UDFGetPartNumByPhysLba(Vcb, FileInfo->ParentFile->Dloc->FELoc.Mapping[0].extLocation);
4137 } else {
4138 BrutePoint();
4139 }
4140 }
4141#ifdef UDF_CHECK_DISK_ALLOCATION
4142 if( FileInfo->Fcb &&
4143 UDFGetFreeBit(((uint32*)(Vcb->FSBM_Bitmap)), FileInfo->Dloc->FELoc.Mapping[0].extLocation)) {
4144
4147 UDFPrint((" Not DELETED SDir\n"));
4148 BrutePoint();
4149 }
4150 ASSERT(!FileInfo->Dloc->FELoc.Modified);
4151 } else
4152 if(!FileInfo->FileIdent ||
4153 !(FileInfo->FileIdent->fileCharacteristics & FILE_DELETED)) {
4154 if(!FileInfo->FileIdent)
4155 AdPrint((" No FileIdent\n"));
4156 if(FileInfo->FileIdent &&
4157 !(FileInfo->FileIdent->fileCharacteristics & FILE_DELETED))
4158 AdPrint((" Not DELETED\n"));
4159 AdPrint(("Flushing to Discarded block %x\n", FileInfo->Dloc->FELoc.Mapping[0].extLocation));
4160 BrutePoint();
4161 }
4162 }
4163#endif // UDF_CHECK_DISK_ALLOCATION
4164
4165 // flush FE and pre-allocation charge for directories
4166 if(FileInfo->Dloc &&
4167 FileInfo->Dloc->DirIndex) {
4168 // if Lite Flush is used, keep preallocations
4169 if(!(FlushFlags & UDF_FLUSH_FLAGS_LITE)) {
4170full_flush:
4172 if(FileInfo->Dloc->DataLoc.Flags & EXTENT_FLAG_PREALLOCATED) {
4173 FileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_CUT_PREALLOCATED;
4174 status = UDFResizeExtent(Vcb, PartNum, UDFGetFileSize(FileInfo), FALSE, &(FileInfo->Dloc->DataLoc));
4176 if(OS_SUCCESS(status)) {
4177 AdPrint(("Dir pre-alloc truncated (Flush)\n"));
4178 FileInfo->Dloc->DataLoc.Modified = TRUE;
4179 }
4180 }
4181 }
4182 }
4183 // flush FE
4184 if(!OS_SUCCESS(status = UDFFlushFE(Vcb, FileInfo, PartNum))) {
4185 UDFPrint(("Error flushing FE\n"));
4186 BrutePoint();
4187 if(FlushFlags & UDF_FLUSH_FLAGS_LITE) {
4188 UDFPrint((" flush pre-alloc\n"));
4189 FlushFlags &= ~UDF_FLUSH_FLAGS_LITE;
4190 goto full_flush;
4191 }
4192 if(FileInfo->Index >= 2) {
4193 PDIR_INDEX_ITEM DirNdx;
4195 if(DirNdx) {
4196 UDFPrint(("Recovery: mark as deleted & flush FI\n"));
4199 FileInfo->FileIdent->fileCharacteristics |= FILE_DELETED;
4200 UDFFlushFI(Vcb, FileInfo, PartNum);
4201 }
4202 }
4203 return status;
4204 }
4205 if(!OS_SUCCESS(status = UDFFlushFI(Vcb, FileInfo, PartNum)))
4206 return status;
4207
4208 ASSERT((FileInfo->Dloc->FileEntry->descVersion == 2) ||
4209 (FileInfo->Dloc->FileEntry->descVersion == 3));
4210
4211 return STATUS_SUCCESS;
4212} // end UDFFlushFile__()
4213
4214/*
4215 This routine compares 2 FileInfo structures
4216 */
4217BOOLEAN
4221 )
4222{
4223 uint_di i;
4224 PDIR_INDEX_HDR hDirIndex1;
4225 PDIR_INDEX_HDR hDirIndex2;
4226 PDIR_INDEX_ITEM DirIndex1;
4227 PDIR_INDEX_ITEM DirIndex2;
4228
4229 if(!f1 || !f2) return FALSE;
4230 if(f1->Dloc->FileEntryLen != f2->Dloc->FileEntryLen) return FALSE;
4231// if(f1->FileIdentLen != f2->FileIdentLen) return FALSE;
4232/* if(f1->Dloc->DirIndex && !f2->Dloc->DirIndex) return FALSE;
4233 if(f2->Dloc->DirIndex && !f1->Dloc->DirIndex) return FALSE;
4234 if((f1->Dloc->DirIndex) &&
4235 (f1->Dloc->DirIndex->LastFrameCount != f2->Dloc->DirIndex->LastFrameCount)) return FALSE;*/
4236 if(f1->Index != f2->Index) return FALSE;
4237 if(!(f1->Dloc->DataLoc.Mapping)) return FALSE;
4238 if(!(f2->Dloc->DataLoc.Mapping)) return FALSE;
4239 if(f1->Dloc->DataLoc.Mapping[0].extLocation != f2->Dloc->DataLoc.Mapping[0].extLocation) return FALSE;
4240 if(f1->Dloc->DataLoc.Mapping[0].extLength != f2->Dloc->DataLoc.Mapping[0].extLength) return FALSE;
4241// if(f1-> != f2->) return FALSE;
4242// if(f1-> != f2->) return FALSE;
4243// if(f1-> != f2->) return FALSE;
4244 if(!(f1->Dloc->FileEntry)) return FALSE;
4245 if(!(f2->Dloc->FileEntry)) return FALSE;
4246 if(RtlCompareMemory(f1->Dloc->FileEntry, f2->Dloc->FileEntry, f2->Dloc->FileEntryLen) != f2->Dloc->FileEntryLen)
4247 return FALSE;
4248 if(!(hDirIndex1 = f1->Dloc->DirIndex)) return FALSE;
4249 if(!(hDirIndex2 = f2->Dloc->DirIndex)) return FALSE;
4250
4251 for(i=2; (DirIndex1 = UDFDirIndex(hDirIndex1,i)) &&
4252 (DirIndex2 = UDFDirIndex(hDirIndex2,i)); i++) {
4253 if( DirIndex1->FName.Buffer &&
4254 !DirIndex2->FName.Buffer)
4255 return FALSE;
4256 if( DirIndex2->FName.Buffer &&
4257 !DirIndex1->FName.Buffer)
4258 return FALSE;
4259 if(!DirIndex2->FName.Buffer &&
4260 !DirIndex1->FName.Buffer)
4261 continue;
4262 if(RtlCompareUnicodeString(&(DirIndex1->FName),
4263 &(DirIndex2->FName),FALSE)) {
4264 return FALSE;
4265 }
4266// if(DirIndex1[i].FileEntry != DirIndex2[i].FileEntry)
4267// return FALSE;
4268 if(RtlCompareMemory(&(DirIndex1->FileEntryLoc),
4269 &(DirIndex2->FileEntryLoc), sizeof(lb_addr)) != sizeof(lb_addr))
4270 return FALSE;
4271 }
4272
4273 return TRUE;
4274} // end UDFCompareFileInfo()
4275
4276/*
4277 This routine computes 32-bit hash based on CRC-32 from SSH
4278 */
4279
4280#ifdef _MSC_VER
4281#pragma warning(push)
4282#pragma warning(disable:4035) // re-enable below
4283#endif
4284
4285#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
4286__declspec (naked)
4287#endif // _X86_
4288uint32
4291 IN uint8* s, // ECX
4292 IN uint32 len // EDX
4293 )
4294{
4295#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
4296// uint32 _Size = len;
4297
4298 __asm {
4299 push ebx
4300 push ecx
4301 push edx
4302 push esi
4303
4304 xor eax,eax
4305 mov esi,ecx // ESI <- s
4306 mov ecx,edx // ECX <- len
4307
4308 jecxz EO_CRC
4309
4310 lea ebx,[crc32_tab]
4311 xor edx,edx
4312
4313CRC_loop:
4314
4315 mov dl,al
4316 xor dl,[esi]
4317 shr eax,8
4318 xor eax,[dword ptr ebx+edx*4]
4319 inc esi
4320 loop CRC_loop
4321
4322EO_CRC:
4323
4324 pop esi
4325 pop edx
4326 pop ecx
4327 pop ebx
4328
4329 ret
4330 }
4331#else // NO X86 optimization , use generic C/C++
4332 uint32 i;
4333 uint32 crc32val = 0;
4334
4335 for(i=0; i<len; i++, s++) {
4336 crc32val =
4337 crc32_tab[(crc32val ^ (*s)) & 0xff] ^ (crc32val >> 8);
4338 }
4339 return crc32val;
4340#endif // _X86_
4341} // end crc32()
4342
4343/*
4344 Calculate a 16-bit CRC checksum for unicode strings
4345 using ITU-T V.41 polynomial.
4346
4347 The OSTA-UDF(tm) 1.50 standard states that using CRCs is mandatory.
4348 The polynomial used is: x^16 + x^12 + x^15 + 1
4349*/
4350
4351#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
4352__declspec (naked)
4353#endif // _X86_
4354uint16
4357 PWCHAR s, // ECX
4358 uint32 n // EDX
4359 )
4360{
4361#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
4362// uint32 _Size = n;
4363
4364 __asm {
4365 push ebx
4366 push ecx
4367 push edx
4368 push esi
4369
4370 xor eax,eax
4371 mov esi,ecx
4372 mov ecx,edx
4373
4374 jecxz EO_uCRC
4375
4376 lea ebx,[CrcTable]
4377 xor edx,edx
4378
4379uCRC_loop:
4380
4381 mov dl,ah // dl = (Crc >> 8)
4382 xor dl,[esi+1] // dl = ((Crc >> 8) ^ (*s >> 8)) & 0xff
4383 mov ah,al
4384 mov al,dh // ax = (Crc << 8)
4385 xor ax,[word ptr ebx+edx*2] // ax = ...........
4386
4387 mov dl,ah
4388 xor dl,[esi]
4389 mov ah,al
4390 mov al,dh
4391 xor ax,[word ptr ebx+edx*2]
4392
4393 inc esi
4394 inc esi
4395 loop uCRC_loop
4396
4397EO_uCRC:
4398
4399 pop esi
4400 pop edx
4401 pop ecx
4402 pop ebx
4403
4404 ret
4405 }
4406#else // NO X86 optimization , use generic C/C++
4407 uint16 Crc = 0;
4408 while (n--) {
4409 Crc = CrcTable[(Crc >> 8 ^ (*s >> 8)) & 0xff] ^ (Crc << 8);
4410 Crc = CrcTable[(Crc >> 8 ^ (*s++ & 0xff)) & 0xff] ^ (Crc << 8);
4411 }
4412 return Crc;
4413
4414#endif // _X86_
4415} // end UDFUnicodeCksum()
4416
4417#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
4418__declspec (naked)
4419#endif // _X86_
4420uint16
4423 PWCHAR s, // ECX
4424 uint32 n // EDX
4425 )
4426{
4427#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
4428// uint32 _Size = n;
4429
4430 __asm {
4431 push ebx
4432 push ecx
4433 push edx
4434 push esi
4435 push edi
4436
4437 xor eax,eax
4438 mov esi,ecx
4439 mov ecx,edx
4440 xor edi,edi
4441
4442 jecxz EO_uCRC
4443
4444 //lea ebx,[CrcTable]
4445 xor edx,edx
4446 xor ebx,ebx
4447
4448uCRC_loop:
4449
4450 mov dl,ah // dl = (Crc >> 8)
4451 or edi,edx // if(*s & 0xff00) Use16 = TRUE;
4452 xor dl,[esi+1] // dl = ((Crc >> 8) ^ (*s >> 8)) & 0xff
4453 mov ah,al
4454 mov al,0 // ax = (Crc << 8)
4455 xor ax,[word ptr CrcTable+edx*2] // ax = ...........
4456
4457 mov dl,ah
4458 xor dl,[esi]
4459 mov ah,al
4460 mov al,0
4462
4463 or edi,edi // if(!Use16) {
4464 jnz use16_1
4465
4466 rol eax,16
4467
4468 mov bl,ah // dl = (Crc >> 8)
4469 xor bl,[esi] // dl = ((Crc >> 8) ^ (*s >> 8)) & 0xff
4470 mov ah,al
4471 mov al,0 // ax = (Crc << 8)
4472 xor ax,[word ptr CrcTable+ebx*2] // ax = ...........
4473
4474 rol eax,16
4475use16_1:
4476 inc esi
4477 inc esi
4478 loop uCRC_loop
4479
4480EO_uCRC:
4481
4482 or edi,edi // if(!Use16) {
4483 jnz use16_2
4484
4485 rol eax,16 // }
4486use16_2:
4487 and eax,0xffff
4488
4489 pop edi
4490 pop esi
4491 pop edx
4492 pop ecx
4493 pop ebx
4494
4495 ret
4496 }
4497#else // NO X86 optimization , use generic C/C++
4498 uint16 Crc = 0;
4499 uint16 Crc2 = 0;
4500 BOOLEAN Use16 = FALSE;
4501 while (n--) {
4502 if(!Use16) {
4503 if((*s) & 0xff00) {
4504 Use16 = TRUE;
4505 } else {
4506 Crc2 = CrcTable[(Crc2 >> 8 ^ (*s >> 8)) & 0xff] ^ (Crc2 << 8);
4507 }
4508 }
4509 Crc = CrcTable[(Crc >> 8 ^ (*s >> 8)) & 0xff] ^ (Crc << 8);
4510 Crc = CrcTable[(Crc >> 8 ^ (*s++ & 0xff)) & 0xff] ^ (Crc << 8);
4511 }
4512 return Use16 ? Crc : Crc2;
4513#endif // _X86_
4514} // end UDFUnicodeCksum150()
4515
4516/*
4517 Calculate a 16-bit CRC checksum using ITU-T V.41 polynomial.
4518
4519 The OSTA-UDF(tm) 1.50 standard states that using CRCs is mandatory.
4520 The polynomial used is: x^16 + x^12 + x^15 + 1
4521*/
4522#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
4523__declspec (naked)
4524#endif // _X86_
4525uint16
4528 IN uint8* Data, // ECX
4529 IN SIZE_T Size // EDX
4530 )
4531{
4532#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
4533// uint32 _Size = Size;
4534
4535 __asm {
4536 push ebx
4537 push ecx
4538 push edx
4539 push esi
4540
4541 mov esi,ecx
4542 mov ecx,edx
4543 xor eax,eax
4544
4545 jecxz EO_CRC
4546
4547 lea ebx,[CrcTable]
4548 xor edx,edx
4549
4550CRC_loop:
4551
4552 mov dl,ah
4553 xor dl,[esi]
4554 mov ah,al
4555 mov al,dh
4556 xor ax,[word ptr ebx+edx*2]
4557 inc esi
4558 loop CRC_loop
4559
4560EO_CRC:
4561
4562 pop esi
4563 pop edx
4564 pop ecx
4565 pop ebx
4566
4567 ret
4568 }
4569#else // NO X86 optimization , use generic C/C++
4570 uint16 Crc = 0;
4571 while (Size--)
4572 Crc = CrcTable[(Crc >> 8 ^ *Data++) & 0xff] ^ (Crc << 8);
4573 return Crc;
4574#endif // _X86_
4575
4576} // end UDFCrc()
4577
4578#ifdef _MSC_VER
4579#pragma warning(pop) // re-enable warning #4035
4580#endif
4581
4582/*
4583 Read the first block of a tagged descriptor & check it.
4584*/
4587 PVCB Vcb,
4588 int8* Buf,
4589 uint32 Block,
4590 uint32 Location,
4591 uint16 *Ident
4592 )
4593{
4594 OSSTATUS RC;
4595 tag* PTag = (tag*)Buf;
4596// icbtag* Icb = (icbtag*)(Buf+1);
4598 unsigned int i;
4600 int8* tb;
4601
4602 // Read the block
4603 if(Block == 0xFFFFFFFF)
4604 return NULL;
4605
4606 _SEH2_TRY {
4607 RC = UDFReadSectors(Vcb, FALSE, Block, 1, FALSE, Buf, &ReadBytes);
4608 if(!OS_SUCCESS(RC)) {
4609 UDFPrint(("UDF: Block=%x, Location=%x: read failed\n", Block, Location));
4610 try_return(RC);
4611 }
4612
4613 *Ident = PTag->tagIdent;
4614
4615 if(Location != PTag->tagLocation) {
4616 UDFPrint(("UDF: location mismatch block %x, tag %x != %x\n",
4617 Block, PTag->tagLocation, Location));
4619 }
4620
4621 /* Verify the tag checksum */
4622 checksum = 0;
4623 tb = Buf;
4624 for (i=0; i<sizeof(tag); i++, tb++)
4625 checksum += (uint8)((i!=4) ? (*tb) : 0);
4626
4627 if(checksum != PTag->tagChecksum) {
4628 UDFPrint(("UDF: tag checksum failed block %x\n", Block));
4630 }
4631
4632 // Verify the tag version
4633 if((PTag->descVersion != 2) &&
4634 (PTag->descVersion != 3)) {
4635 UDFPrint(("UDF: Tag version 0x%04x != 0x0002 || 0x0003 block %x\n",
4636 (PTag->descVersion), Block));
4638 }
4639
4640 // Verify the descriptor CRC
4641 if(((PTag->descCRCLength) + sizeof(tag) > Vcb->BlockSize) ||
4642 ((PTag->descCRC) == UDFCrc((uint8*)Buf + sizeof(tag), PTag->descCRCLength)) ||
4643 !(PTag->descCRC) ) {
4644 /* UDFPrint(("Tag ID: %x, ver %x\t", PTag->tagIdent, PTag->descVersion ));
4645 if((i == TID_FILE_ENTRY) ||
4646 (i == TID_EXTENDED_FILE_ENTRY)) {
4647 UDFPrint(("StrategType: %x, ", Icb->strategyType ));
4648 UDFPrint(("FileType: %x\t", Icb->fileType ));
4649 }
4650 UDFPrint(("\n"));*/
4652 }
4653 UDFPrint(("UDF: Crc failure block %x: crc = %x, crclen = %x\n",
4654 Block, PTag->descCRC, PTag->descCRCLength));
4655 RC = STATUS_CRC_ERROR;
4656
4657try_exit: NOTHING;
4658
4659 } _SEH2_FINALLY {
4660 ;
4661 } _SEH2_END
4662
4663 return RC;
4664} // end UDFReadTagged()
4665
4666#ifndef UDF_READ_ONLY_BUILD
4667/*
4668 This routine creates hard link for the file from DirInfo1
4669 to DirInfo2 & names it as fn
4670 */
4673 IN PVCB Vcb,
4675 IN OUT BOOLEAN* Replace, // replace if destination file exists
4676 IN PUNICODE_STRING fn, // destination
4677 IN OUT PUDF_FILE_INFO DirInfo1,
4678 IN OUT PUDF_FILE_INFO DirInfo2,
4679 IN OUT PUDF_FILE_INFO FileInfo // source (opened)
4680 )
4681{
4682 PUDF_FILE_INFO FileInfo2;
4684 PDIR_INDEX_ITEM DirNdx1;
4685 PDIR_INDEX_ITEM DirNdx2;
4686 uint_di i;
4687 BOOLEAN Recovery = FALSE;
4688 BOOLEAN SameFE = FALSE;
4689 uint32 NTAttr = 0;
4690
4691 // validate FileInfo
4692 ValidateFileInfo(DirInfo1);
4693 ValidateFileInfo(DirInfo2);
4695
4697 // too many links to file...
4698 return STATUS_TOO_MANY_LINKS;
4699 }
4700
4701 i = 0;
4702 if(DirInfo1 == DirInfo2) {
4703 if(OS_SUCCESS(status = UDFFindFile(Vcb, IgnoreCase, TRUE, fn, DirInfo2, &i)) &&
4704 (i==FileInfo->Index) ) {
4705 // case-only difference
4707 }
4708 }
4709
4710 // PHASE 0
4711 // try to create new FileIdent & FileEntry in Dir2
4712
4713HLinkRetry:
4715 0, (FileInfo->Dloc->FileEntry->tagIdent == TID_EXTENDED_FILE_ENTRY),
4716 TRUE, DirInfo2, &FileInfo2))) {
4717 if(UDFCleanUpFile__(Vcb, FileInfo2) && FileInfo2)
4718 MyFreePool__(FileInfo2);
4720 // try to recover >;->
4721 if((*Replace) && !Recovery) {
4722 Recovery = TRUE;
4723 status = UDFOpenFile__(Vcb, IgnoreCase, TRUE, fn, DirInfo2, &FileInfo2, NULL);
4724 if(OS_SUCCESS(status)) {
4725 status = UDFDoesOSAllowFileToBeTargetForHLink__(FileInfo2);
4726 if(!OS_SUCCESS(status)) {
4727 UDFCloseFile__(Vcb, FileInfo2);
4728 goto cleanup_and_abort_hlink;
4729 }
4730 if((FileInfo->Dloc == FileInfo2->Dloc) &&
4731 (FileInfo != FileInfo2)) {
4732 SameFE = TRUE;
4733 // 'status' is already STATUS_SUCCESS here
4734 } else {
4735 status = UDFUnlinkFile__(Vcb, FileInfo2, TRUE);
4736 }
4737 UDFCloseFile__(Vcb, FileInfo2);
4738 if(UDFCleanUpFile__(Vcb, FileInfo2)) {
4739 MyFreePool__(FileInfo2);
4740 FileInfo2 = NULL;
4741 if(SameFE)
4742 return STATUS_SUCCESS;
4743 } else {
4744 // we get here if the FileInfo has associated
4745 // system-specific Fcb
4746 // Such fact means that not all system references
4747 // has already gone (except Linked file case)
4748 if(SameFE)
4749 return STATUS_SUCCESS;
4750 if(!OS_SUCCESS(status) ||
4753 }
4754 if(OS_SUCCESS(status)) goto HLinkRetry;
4755 }
4756cleanup_and_abort_hlink:
4757 if(FileInfo2 && UDFCleanUpFile__(Vcb, FileInfo2)) {
4758 MyFreePool__(FileInfo2);
4759 FileInfo2 = NULL;
4760 }
4761 } else {
4763 }
4764 }
4765 return status;
4766 }
4767 // update pointers
4768 DirNdx1 = UDFDirIndex(DirInfo1->Dloc->DirIndex, FileInfo->Index);
4769 DirNdx2 = UDFDirIndex(DirInfo2->Dloc->DirIndex, FileInfo2->Index);
4770
4771 // copy file attributes to newly created FileIdent
4772 NTAttr = UDFAttributesToNT(DirNdx1, FileInfo->Dloc->FileEntry);
4773 FileInfo2->FileIdent->fileVersionNum = FileInfo->FileIdent->fileVersionNum;
4774
4775 // PHASE 1
4776 // copy all necessary info from FileInfo to FileInfo2
4777
4778 FileInfo2->FileIdent->icb = FileInfo->FileIdent->icb;
4779 FileInfo2->FileIdent->fileCharacteristics = FileInfo->FileIdent->fileCharacteristics;
4780 FileInfo2->FileIdent->fileVersionNum = FileInfo->FileIdent->fileVersionNum;
4781
4782 DirNdx2->FileCharacteristics = DirNdx1->FileCharacteristics & ~FILE_DELETED;
4783 DirNdx2->FileEntryLoc = DirNdx1->FileEntryLoc;
4784 DirNdx2->FI_Flags = (DirNdx1->FI_Flags & ~UDF_FI_FLAG_SYS_ATTR) | UDF_FI_FLAG_FI_MODIFIED | UDF_FI_FLAG_LINKED;
4785
4786 UDFAttributesToUDF(DirNdx2, FileInfo2->Dloc->FileEntry, NTAttr);
4787
4788 // PHASE 2
4789 // update FileInfo
4790
4791 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
4792 DirNdx1->FI_Flags = DirNdx2->FI_Flags;
4793 UDFIncFileLinkCount(FileInfo); // increase to 1
4794// UDFUpdateModifyTime(Vcb, FileInfo);
4795 FileInfo->Dloc->LinkRefCount += FileInfo2->Dloc->LinkRefCount;
4796 if(FileInfo2->FileIdent)
4797 ((FidADImpUse*)&(FileInfo2->FileIdent->icb.impUse))->uniqueID = (uint32)UDFAssingNewFUID(Vcb);
4798
4799 // PHASE 3
4800 // drop all unnecessary info from FileInfo2
4801
4802 UDFFreeFESpace(Vcb, DirInfo2, &(FileInfo2->Dloc->FELoc));
4803 UDFRemoveDloc(Vcb, FileInfo2->Dloc);
4804
4805 // PHASE 4
4806 // perform in-memory linkage (update driver's tree structures) and flush
4807
4808 FileInfo2->Dloc = FileInfo->Dloc;
4809 UDFInsertLinkedFile(FileInfo2, FileInfo);
4810
4811 UDFCloseFile__(Vcb, FileInfo2);
4812 if(UDFCleanUpFile__(Vcb, FileInfo2)) {
4813 MyFreePool__(FileInfo2);
4814 }
4815 // return 'delete target' status
4816 (*Replace) = Recovery;
4817
4818 return STATUS_SUCCESS;
4819} // end UDFHardLinkFile__()
4820
4821/*
4822 This routine allocates FileEntry with in-ICB zero-sized data
4823 If it returns status != STATUS_SUCCESS caller should call UDFCleanUpFile__
4824 for returned pointer *WITHOUT* using UDFCloseFile__
4825 */
4828 IN PVCB Vcb,
4829// IN uint16 AllocMode, // short/long/ext/in-icb // always in-ICB
4830 IN uint32 PartNum,
4831 IN uint32 ExtAttrSz,
4832 IN uint32 ImpUseLen,
4833 IN BOOLEAN Extended,
4834 OUT PUDF_FILE_INFO* _FileInfo
4835 )
4836{
4838 LONG_AD FEicb;
4840 *_FileInfo = NULL;
4842
4844 *_FileInfo = FileInfo;
4845 if(!FileInfo)
4847 ImpUseLen = (ImpUseLen + 3) & ~((uint16)3);
4848
4850 // init horizontal links
4851 FileInfo->NextLinkedFile =
4852 FileInfo->PrevLinkedFile = FileInfo;
4853 // allocate space for FileEntry
4854 if(!OS_SUCCESS(status =
4855 UDFBuildFileEntry(Vcb, NULL, FileInfo, PartNum, ICB_FLAG_AD_IN_ICB, ExtAttrSz, Extended) ))
4856 return status;
4857 FEicb.extLength = Vcb->LBlockSize;
4858 FEicb.extLocation.logicalBlockNum = UDFPhysLbaToPart(Vcb, PartNum, FileInfo->Dloc->FELoc.Mapping[0].extLocation);
4859 FEicb.extLocation.partitionReferenceNum = (uint16)PartNum;
4860 RtlZeroMemory(&(FEicb.impUse), sizeof(FEicb.impUse));
4861
4862 FileInfo->Dloc->DataLoc.Mapping = UDFExtentToMapping(&(FileInfo->Dloc->FELoc.Mapping[0]));
4863 if(!(FileInfo->Dloc->DataLoc.Mapping)) return STATUS_INSUFFICIENT_RESOURCES;
4864 FileInfo->Dloc->DataLoc.Length = 0;
4865 FileInfo->Dloc->DataLoc.Offset = FileInfo->Dloc->FileEntryLen;
4866 // init FileEntry
4869 UDFIncFileLinkCount(FileInfo); // increase to 1
4870 UDFUpdateCreateTime(Vcb, FileInfo);
4871 // zero sector for FileEntry
4872 FileInfo->Dloc->DataLoc.Mapping[0].extLength &= UDF_EXTENT_LENGTH_MASK;
4873 FileInfo->Dloc->FELoc.Mapping[0].extLength &= UDF_EXTENT_LENGTH_MASK;
4874 status = UDFWriteData(Vcb, TRUE, ((int64)(FileInfo->Dloc->FELoc.Mapping[0].extLocation)) << Vcb->BlockSizeBits, Vcb->LBlockSize, FALSE, Vcb->ZBuffer, &ReadBytes);
4875 if(!OS_SUCCESS(status))
4876 return status;
4877
4879 UDFReleaseDloc(Vcb, FileInfo->Dloc);
4880 return STATUS_SUCCESS;
4881} // end UDFCreateRootFile__()
4882
4883/*
4884 This routine tries to create StreamDirectory associated with given file
4885 Caller should use UDFCleanUpFile__ if returned status != STATUS_SUCCESS
4886 */
4889 IN PVCB Vcb,
4890 IN PUDF_FILE_INFO FileInfo, // file containing stream-dir
4891 OUT PUDF_FILE_INFO* _SDirInfo // this is to be filled & doesn't contain
4892 // any pointers
4893 )
4894{
4896 PUDF_FILE_INFO SDirInfo;
4897 uint16 Ident;
4898
4899 *_SDirInfo = NULL;
4901 // check currently recorded UDF revision
4904 // check if we are allowed to associate Stream Dir with this file
4905 if((FileInfo->ParentFile && UDFIsAStreamDir(FileInfo->ParentFile)) ||
4907 return STATUS_FILE_DELETED;
4908 // check if we have Deleted SDir
4909 if(FileInfo->Dloc->SDirInfo &&
4910 UDFIsSDirDeleted(FileInfo->Dloc->SDirInfo))
4911 return STATUS_ACCESS_DENIED;
4912 // check if this file has ExtendedFileEntry
4913 if((Ident = FileInfo->Dloc->FileEntry->tagIdent) != TID_EXTENDED_FILE_ENTRY) {
4915 return status;
4916 }
4917
4918 uint32 PartNum = UDFGetPartNumByPhysLba(Vcb, FileInfo->Dloc->FELoc.Mapping[0].extLocation);
4919 // create stream directory file
4920 if(!OS_SUCCESS(status = UDFCreateRootFile__(Vcb, PartNum, 0,0,FALSE, &SDirInfo)))
4921 return status;
4922 // link objects
4923 SDirInfo->ParentFile = FileInfo;
4924 // record directory structure
4926
4927 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_HAS_SDIR;
4929 FileInfo->Dloc->FE_Flags &= ~UDF_FE_FLAG_HAS_SDIR;
4930
4931 status = UDFRecordDirectory__(Vcb, SDirInfo);
4933
4934 UDFInterlockedIncrement((PLONG)&(FileInfo->OpenCount));
4935 if(!OS_SUCCESS(status)) {
4936 UDFUnlinkFile__(Vcb, SDirInfo, TRUE);
4937 UDFCloseFile__(Vcb, SDirInfo);
4938 UDFCleanUpFile__(Vcb, SDirInfo);
4939 MyFreePool__(SDirInfo);
4940 ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->streamDirectoryICB.extLength = 0;
4941 ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->streamDirectoryICB.extLocation.partitionReferenceNum = 0;
4942 ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->streamDirectoryICB.extLocation.logicalBlockNum = 0;
4943 return status;
4944 }
4945 *_SDirInfo = SDirInfo;
4946 // do some init
4947 ((PEXTENDED_FILE_ENTRY)(SDirInfo->Dloc->FileEntry))->icbTag.fileType = UDF_FILE_TYPE_STREAMDIR;
4948 ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->streamDirectoryICB.extLength = Vcb->LBlockSize;
4949 ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->streamDirectoryICB.extLocation.partitionReferenceNum = (uint16)PartNum;
4950 ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->streamDirectoryICB.extLocation.logicalBlockNum =
4951 UDFPhysLbaToPart(Vcb, PartNum, SDirInfo->Dloc->FELoc.Mapping[0].extLocation);
4952 ((PEXTENDED_FILE_ENTRY)(SDirInfo->Dloc->FileEntry))->uniqueID =
4953 ((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->uniqueID;
4955 // open & finalize linkage
4956 FileInfo->Dloc->SDirInfo = SDirInfo;
4957 return STATUS_SUCCESS;
4958} // end UDFCreateStreamDir__()
4959#endif //UDF_READ_ONLY_BUILD
4960
4961/*
4962 This routine opens Stream Directory associated with file specified
4963 */
4966 IN PVCB Vcb,
4967 IN PUDF_FILE_INFO FileInfo, // file containing stream-dir
4968 OUT PUDF_FILE_INFO* _SDirInfo // this is to be filled & doesn't contain
4969 // any pointers
4970 )
4971{
4973 PUDF_FILE_INFO SDirInfo;
4974 PUDF_FILE_INFO ParSDirInfo;
4975 uint16 Ident;
4976
4977 *_SDirInfo = NULL;
4979 // check if this file has ExtendedFileEntry
4980 if((Ident = FileInfo->Dloc->FileEntry->tagIdent) != TID_EXTENDED_FILE_ENTRY) {
4981 return STATUS_NOT_FOUND;
4982 }
4983 if((SDirInfo = FileInfo->Dloc->SDirInfo)) {
4984 // it is already opened. Good...
4985
4986 // check if we have Deleted SDir
4987 if(FileInfo->Dloc->SDirInfo &&
4988 UDFIsSDirDeleted(FileInfo->Dloc->SDirInfo))
4989 return STATUS_FILE_DELETED;
4990 // All right. Look for parallel SDir (if any)
4991 if(SDirInfo->ParentFile != FileInfo) {
4992 ParSDirInfo = UDFLocateParallelFI(FileInfo, 0, SDirInfo);
4993 BrutePoint();
4994 if(ParSDirInfo->ParentFile != FileInfo) {
4996 *_SDirInfo = SDirInfo;
4997 if(!SDirInfo) return STATUS_INSUFFICIENT_RESOURCES;
4998 RtlCopyMemory(SDirInfo, FileInfo->Dloc->SDirInfo, sizeof(UDF_FILE_INFO));
4999 // SDirInfo->NextLinkedFile = FileInfo->Dloc->SDirInfo->NextLinkedFile; // is already done
5000 UDFInsertLinkedFile(SDirInfo, FileInfo->Dloc->SDirInfo);
5001 SDirInfo->RefCount = 0;
5002 SDirInfo->ParentFile = FileInfo;
5003 SDirInfo->Fcb = NULL;
5004 } else {
5005 SDirInfo = ParSDirInfo;
5006 }
5007 }
5008 UDFReferenceFile__(SDirInfo);
5009 *_SDirInfo = SDirInfo;
5010 return STATUS_SUCCESS;
5011 }
5012 // normal open
5013 if(!((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->streamDirectoryICB.extLength)
5014 return STATUS_NOT_FOUND;
5016 if(!SDirInfo) return STATUS_INSUFFICIENT_RESOURCES;
5017 *_SDirInfo = SDirInfo;
5018 status = UDFOpenRootFile__(Vcb, &(((PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry))->streamDirectoryICB.extLocation) ,SDirInfo);
5019 if(!OS_SUCCESS(status)) return status;
5020 // open & finalize linkage
5021 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_HAS_SDIR;
5022 SDirInfo->Dloc->FE_Flags |= UDF_FE_FLAG_IS_SDIR;
5023 FileInfo->Dloc->SDirInfo = SDirInfo;
5024 SDirInfo->ParentFile = FileInfo;
5025
5026 UDFInterlockedIncrement((PLONG)&(FileInfo->OpenCount));
5027
5028 return STATUS_SUCCESS;
5029} // end UDFOpenStreamDir__()
5030
5031#ifndef UDF_READ_ONLY_BUILD
5032/*
5033 This routine records VAT & VAT Icb at the end of session
5034 */
5037 IN PVCB Vcb
5038 )
5039{
5040 uint32 Offset;
5042 uint32 hdrOffset, hdrOffsetNew;
5043 uint32 hdrLen;
5046 uint32 len;
5047 uint16 PartNdx = (uint16)Vcb->VatPartNdx;
5048 uint16 PartNum = UDFGetPartNumByPartNdx(Vcb, PartNdx);
5049 uint32 root = UDFPartStart(Vcb, PartNum);
5050 PUDF_FILE_INFO VatFileInfo = Vcb->VatFileInfo;
5051 uint32 i;
5053 uint32 off, BS, NWA;
5054 int8* Old;
5055 int8* New;
5056 uint32* Vat;
5057 uint8 AllocMode;
5058 uint32 VatLen;
5059 uint32 PacketOffset;
5060 uint32 BSh = Vcb->BlockSizeBits;
5061 uint32 MaxPacket = Vcb->WriteBlockSize >> BSh;
5062 uint32 OldLen;
5063 EntityID* eID;
5064
5065 if(!(Vat = Vcb->Vat) || !VatFileInfo) return STATUS_INVALID_PARAMETER;
5066 // Disable VAT-based translation
5067 Vcb->Vat = NULL;
5068 // sync VAT and FSBM
5069 len = min(UDFPartLen(Vcb, PartNum), Vcb->FSBM_BitCount - root);
5070 len = min(Vcb->VatCount, len);
5071 for(i=0; i<len; i++) {
5072 if(UDFGetFreeBit(Vcb->FSBM_Bitmap, root+i))
5073 Vat[i] = UDF_VAT_FREE_ENTRY;
5074 }
5075 // Ok, now we shall construct new VAT image...
5076 // !!! NOTE !!!
5077 // Both VAT copies - in-memory & on-disc
5078 // contain _relative_ addresses
5079 OldLen = len = (uint32)UDFGetFileSize(Vcb->VatFileInfo);
5080 VatLen = (Vcb->LastLBA - root + 1) * sizeof(uint32);
5081 Old = (int8*)DbgAllocatePool(PagedPool, OldLen);
5082 if(!Old) {
5083 DbgFreePool(Vat);
5085 }
5086 // read old one
5087 status = UDFReadFile__(Vcb, VatFileInfo, 0, OldLen, FALSE, Old, &ReadBytes);
5088 if(!OS_SUCCESS(status)) {
5089 DbgFreePool(Vat);
5090 DbgFreePool(Old);
5091 return status;
5092 }
5093 // prepare some pointers
5094 // and fill headers
5095 if(Vcb->Partitions[PartNdx].PartitionType == UDF_VIRTUAL_MAP15) {
5096 Offset = 0;
5097 to_read =
5098 hdrOffset = len - sizeof(VirtualAllocationTable15);
5099 hdrLen = sizeof(VirtualAllocationTable15);
5100 hdrOffsetNew = VatLen;
5101 New = (int8*)DbgAllocatePool(PagedPool, VatLen + hdrLen);
5102 if(!New) {
5103 DbgFreePool(Vat);
5105 }
5106 RtlCopyMemory(New+hdrOffsetNew, Old+hdrOffset, hdrLen);
5107 ((VirtualAllocationTable15*)(New + hdrOffset))->previousVATICB =
5108 VatFileInfo->Dloc->FELoc.Mapping[0].extLocation - root;
5109 eID = &(((VirtualAllocationTable15*)(New + hdrOffset))->ident);
5110
5112
5113/* RtlCopyMemory((int8*)&(eID->ident), UDF_ID_ALLOC, sizeof(UDF_ID_ALLOC) );
5114 iis = (impIdentSuffix*)&(eID->identSuffix);
5115 iis->OSClass = UDF_OS_CLASS_WINNT;
5116 iis->OSIdent = UDF_OS_ID_WINNT;*/
5117 } else {
5119
5121 to_read = len - Offset;
5122 hdrOffset = 0;
5123 hdrLen = sizeof(VirtualAllocationTable20);
5124 hdrOffsetNew = 0;
5125 New = (int8*)DbgAllocatePool(PagedPool, VatLen + hdrLen);
5126 if(!New) {
5127 DbgFreePool(Vat);
5129 }
5130 RtlCopyMemory(New+hdrOffsetNew, Old+hdrOffset, hdrLen);
5131 ((VirtualAllocationTable20*)New)->previousVatICBLoc =
5132 VatFileInfo->Dloc->FELoc.Mapping[0].extLocation - root;
5133
5135
5136 Buf->minReadRevision = Vcb->minUDFReadRev;
5137 Buf->minWriteRevision = Vcb->minUDFWriteRev;
5138 Buf->maxWriteRevision = Vcb->maxUDFWriteRev;
5139
5140 Buf->numFIDSFiles = Vcb->numFiles;
5141 Buf->numFIDSDirectories = Vcb->numDirs;
5142 }
5143
5144 RtlCopyMemory(New+Offset, Vat, VatLen);
5145 //
5146 if(VatFileInfo->Dloc->FileEntry->tagIdent == TID_EXTENDED_FILE_ENTRY) {
5147 eID = &(((PEXTENDED_FILE_ENTRY)(VatFileInfo->Dloc->FileEntry))->impIdent);
5148 } else {
5149 eID = &(((PFILE_ENTRY)(VatFileInfo->Dloc->FileEntry))->impIdent);
5150 }
5151
5152#if 0
5154#endif
5155
5156/* RtlCopyMemory((int8*)&(eID->ident), UDF_ID_DEVELOPER, sizeof(UDF_ID_DEVELOPER) );
5157 iis = (impIdentSuffix*)&(eID->identSuffix);
5158 iis->OSClass = UDF_OS_CLASS_WINNT;
5159 iis->OSIdent = UDF_OS_ID_WINNT;*/
5160
5161 VatFileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
5162 // drop VAT
5163 DbgFreePool(Vat);
5164 len = VatLen;
5165 // the operation of resize can modifiy WriteCount in WCache due to movement
5166 // of the data from FE. That's why we should remember PacketOffset now
5167 if(to_read < VatLen) {
5168 status = UDFResizeFile__(Vcb, VatFileInfo, len = hdrLen + VatLen);
5169 if(!OS_SUCCESS(status)) {
5170 return status;
5171 }
5172 UDFMarkSpaceAsXXX(Vcb, VatFileInfo->Dloc, VatFileInfo->Dloc->DataLoc.Mapping, AS_DISCARDED); //free
5173 }
5174 PacketOffset = WCacheGetWriteBlockCount__(&(Vcb->FastCache));
5175 if( ((((PFILE_ENTRY)(VatFileInfo->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK) == ICB_FLAG_AD_IN_ICB) ) {
5176 // now we'll place FE & built-in data to the last sector of
5177 // the last packet will be recorded
5178 if(!PacketOffset) {
5179 // add padding
5180 UDFWriteData(Vcb, TRUE, ((uint64)Vcb->NWA) << Vcb->BlockSizeBits, 1, FALSE, Old, &ReadBytes);
5181 PacketOffset++;
5182 } else {
5183 Vcb->Vat = (uint32*)(New+Offset);
5184 WCacheSyncReloc__(&(Vcb->FastCache), Vcb);
5185 Vcb->Vat = NULL;
5186 }
5187 VatFileInfo->Dloc->FELoc.Mapping[0].extLocation =
5188 VatFileInfo->Dloc->DataLoc.Mapping[0].extLocation =
5189 Vcb->NWA+PacketOffset;
5190 VatFileInfo->Dloc->FELoc.Modified = TRUE;
5191 // setup descTag
5192 ((PFILE_ENTRY)(VatFileInfo->Dloc->FileEntry))->descTag.tagLocation =
5193 UDFPhysLbaToPart(Vcb, PartNum, VatFileInfo->Dloc->DataLoc.Mapping[0].extLocation);
5194 // record data
5195 if(OS_SUCCESS(status = UDFWriteFile__(Vcb, VatFileInfo, 0, VatLen + hdrLen, FALSE, New, &ReadBytes))) {
5196 status = UDFFlushFile__(Vcb, VatFileInfo);
5197 }
5198 return status;
5199 }
5200 // We can't fit the whole VAT in FE tail
5201 // Now lets 'unpack' VAT's mapping to make updating easier
5202 status = UDFUnPackMapping(Vcb, &(VatFileInfo->Dloc->DataLoc));
5203 if(!OS_SUCCESS(status)) return status;
5204 // update VAT with locations of not flushed blocks
5205 if(PacketOffset) {
5206 Vcb->Vat = (uint32*)(New+Offset);
5207 WCacheSyncReloc__(&(Vcb->FastCache), Vcb);
5208 Vcb->Vat = NULL;
5209 }
5210
5211 Mapping = VatFileInfo->Dloc->DataLoc.Mapping;
5212 off=0;
5213 BS = Vcb->BlockSize;
5214 NWA = Vcb->NWA;
5215 VatLen += hdrLen;
5216 // record modified parts of VAT & update mapping
5217 for(i=0; Mapping[i].extLength; i++) {
5218 to_read = (VatLen>=BS) ? BS : VatLen;
5219 if((OldLen < off) || (RtlCompareMemory(Old+off, New+off, to_read) != to_read)) {
5220 // relocate frag
5221 Mapping[i].extLocation = NWA+PacketOffset;
5222 Mapping[i].extLength &= UDF_EXTENT_LENGTH_MASK;
5223 PacketOffset++;
5224 if(PacketOffset >= MaxPacket) {
5225 NWA += (MaxPacket + 7);
5226 PacketOffset = 0;
5227 }
5228 status = UDFWriteFile__(Vcb, VatFileInfo, off, to_read, FALSE, New+off, &ReadBytes);
5229 if(!OS_SUCCESS(status)) {
5230 return status;
5231 }
5232 }
5233 VatLen-=BS;
5234 off+=BS;
5235 }
5236 // pack mapping
5237 UDFPackMapping(Vcb, &(VatFileInfo->Dloc->DataLoc));
5238 len = UDFGetMappingLength(VatFileInfo->Dloc->DataLoc.Mapping)/sizeof(EXTENT_MAP) - 1;
5239 // obtain AllocMode
5240 AllocMode = ((PFILE_ENTRY)(VatFileInfo->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK;
5241 switch(AllocMode) {
5242 case ICB_FLAG_AD_SHORT: {
5243 AllocMode = sizeof(SHORT_AD);
5244 break;
5245 }
5246 case ICB_FLAG_AD_LONG: {
5247 AllocMode = sizeof(LONG_AD);
5248 break;
5249 }
5250 case ICB_FLAG_AD_EXTENDED: {
5251// break;
5252 }
5253 default: {
5255 }
5256 }
5257 // calculate actual AllocSequence length (in blocks)
5258 len = (len*AllocMode+BS-1+VatFileInfo->Dloc->AllocLoc.Offset) /
5259// (((BS - sizeof(ALLOC_EXT_DESC))/sizeof(SHORT_AD))*sizeof(SHORT_AD));
5260 ((BS - sizeof(ALLOC_EXT_DESC) + AllocMode - 1) & ~(AllocMode-1));
5261 // Re-init AllocLoc
5262 if(VatFileInfo->Dloc->AllocLoc.Mapping) MyFreePool__(VatFileInfo->Dloc->AllocLoc.Mapping);
5265 if(!(VatFileInfo->Dloc->AllocLoc.Mapping)) return STATUS_INSUFFICIENT_RESOURCES;
5266
5267 VatFileInfo->Dloc->AllocLoc.Offset = (uint32)(VatFileInfo->Dloc->FELoc.Length);
5268 VatFileInfo->Dloc->AllocLoc.Length = 0;
5269 Mapping = VatFileInfo->Dloc->AllocLoc.Mapping;
5270 Mapping[0].extLength = BS-VatFileInfo->Dloc->AllocLoc.Offset;
5271// Mapping[0].extLocation = ???;
5272 for(i=1; i<len; i++) {
5273 // relocate frag
5274 Mapping[i].extLocation = NWA+PacketOffset;
5275 Mapping[i].extLength = BS;
5276 PacketOffset++;
5277 if(PacketOffset >= MaxPacket) {
5278 NWA += (MaxPacket + 7);
5279 PacketOffset = 0;
5280 }
5281 }
5282 // Terminator
5283 Mapping[i].extLocation =
5284 Mapping[i].extLength = 0;
5285
5286 if( !PacketOffset &&
5287 (VatFileInfo->Dloc->AllocLoc.Length <= (Vcb->BlockSize - (uint32)(VatFileInfo->Dloc->AllocLoc.Offset)) ) ) {
5288 // add padding
5289 UDFWriteData(Vcb, TRUE, ((uint64)NWA) << Vcb->BlockSizeBits, 1, FALSE, Old, &ReadBytes);
5290 PacketOffset++;
5291 }
5292 // now we'll place FE & built-in data to the last sector of
5293 // the last packet will be recorded
5294 VatFileInfo->Dloc->FELoc.Mapping[0].extLocation =
5295 VatFileInfo->Dloc->AllocLoc.Mapping[0].extLocation =
5296 NWA+PacketOffset;
5297 VatFileInfo->Dloc->FELoc.Modified = TRUE;
5298 // setup descTag
5299 ((PFILE_ENTRY)(VatFileInfo->Dloc->FileEntry))->descTag.tagLocation =
5300 UDFPhysLbaToPart(Vcb, PartNum, VatFileInfo->Dloc->FELoc.Mapping[0].extLocation);
5301 VatFileInfo->Dloc->DataLoc.Modified = TRUE;
5302
5303 status = UDFFlushFile__(Vcb, VatFileInfo);
5304 if(!OS_SUCCESS(status))
5305 return status;
5306 WCacheFlushAll__(&(Vcb->FastCache), Vcb);
5307 return STATUS_SUCCESS;
5308} // end UDFRecordVAT()
5309#endif //UDF_READ_ONLY_BUILD
5310
5311/*
5312 This routine updates VAT according to RequestedLbaTable (RelocTab) &
5313 actual physical address where this data will be stored
5314 */
5317 IN void* _Vcb,
5318 IN uint32 Lba,
5319 IN uint32* RelocTab, // can be NULL
5320 IN uint32 BCount
5321 )
5322{
5323#ifndef UDF_READ_ONLY_BUILD
5324 PVCB Vcb = (PVCB)_Vcb;
5325 uint16 PartNdx = (uint16)(Vcb->VatPartNdx);
5326 uint16 PartNum = (uint16)(Lba ? UDFGetPartNumByPhysLba(Vcb, Lba) : UDFGetPartNumByPartNdx(Vcb, PartNdx));
5327 if(PartNum != UDFGetPartNumByPartNdx(Vcb, PartNdx)) {
5328 UDFPrint(("UDFUpdateVAT: Write to Write-Protected partition\n"));
5330 }
5331 // !!! NOTE !!!
5332 // Both VAT copies - in-memory & on-disc
5333 // contain _relative_ addresses
5334 uint32 root = Vcb->Partitions[PartNdx].PartitionRoot;
5335 uint32 NWA = Vcb->NWA-root;
5336 uint32 i;
5337 uint32 CurLba;
5338
5339 if(!Vcb->Vat) return STATUS_SUCCESS;
5340
5341 for(i=0; i<BCount; i++, NWA++) {
5342 if((CurLba = (RelocTab ? RelocTab[i] : (Lba+i)) - root) >= Vcb->VatCount)
5343 Vcb->VatCount = CurLba+1;
5344 Vcb->Vat[CurLba] = NWA;
5345 }
5346 return STATUS_SUCCESS;
5347#else //UDF_READ_ONLY_BUILD
5349#endif //UDF_READ_ONLY_BUILD
5350} // end UDFUpdateVAT()
5351
5352#ifndef UDF_READ_ONLY_BUILD
5353/*
5354 This routine rebuilds file's FE in order to move data from
5355 ICB to separate Block.
5356 */
5359 IN PVCB Vcb,
5361 IN uint8 NewAllocMode
5362 )
5363{
5365 int8* OldInIcb = NULL;
5366 uint32 OldLen;
5369 SIZE_T _WrittenBytes;
5370 PUDF_DATALOC_INFO Dloc;
5371
5372// ASSERT(FileInfo->RefCount >= 1);
5373
5374 Dloc = FileInfo->Dloc;
5375 ASSERT(Dloc->FELoc.Mapping[0].extLocation);
5377
5378 if(NewAllocMode == ICB_FLAG_AD_DEFAULT_ALLOC_MODE) {
5379 NewAllocMode = (uint8)(Vcb->DefaultAllocMode);
5380 }
5381 // we do not support recording of extended AD now
5382 if(NewAllocMode != ICB_FLAG_AD_SHORT &&
5383 NewAllocMode != ICB_FLAG_AD_LONG)
5385 if(!Dloc->DataLoc.Offset || !Dloc->DataLoc.Length)
5386 return STATUS_SUCCESS;
5387 ASSERT(!Dloc->AllocLoc.Mapping);
5388 // read in-icb data. it'll be replaced after resize
5389 OldInIcb = (int8*)MyAllocatePool__(NonPagedPool, (uint32)(Dloc->DataLoc.Length));
5390 if(!OldInIcb)
5392 OldLen = (uint32)(Dloc->DataLoc.Length);
5393 status = UDFReadExtent(Vcb, &(Dloc->DataLoc), 0, OldLen, FALSE, OldInIcb, &ReadBytes);
5394 if(!OS_SUCCESS(status)) {
5395 MyFreePool__(OldInIcb);
5396 return status;
5397 }
5398/* if(!Dloc->AllocLoc.Mapping) {
5399 Dloc->AllocLoc.Mapping = (PEXTENT_MAP)MyAllocatePool__(NonPagedPool, sizeof(EXTENT_MAP)*2);
5400 if(!Dloc->AllocLoc.Mapping) {
5401 MyFreePool__(OldInIcb);
5402 return STATUS_INSUFFICIENT_RESOURCES;
5403 }
5404 }
5405 // init Alloc mode
5406 if((((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK) == ICB_FLAG_AD_IN_ICB) {
5407 ((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags &= ~ICB_FLAG_ALLOC_MASK;
5408 ((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags |= Vcb->DefaultAllocMode;
5409 } else {
5410 BrutePoint();
5411 }
5412 RtlZeroMemory(Dloc->AllocLoc.Mapping, sizeof(EXTENT_MAP)*2);
5413// Dloc->AllocLoc.Mapping[0].extLocation = 0;
5414 Dloc->AllocLoc.Mapping[0].extLength = Vcb->LBlockSize | EXTENT_NOT_RECORDED_NOT_ALLOCATED;
5415// Dloc->AllocLoc.Mapping[1].extLocation = 0;
5416// Dloc->AllocLoc.Mapping[1].extLength = 0;
5417*/
5418
5419 // grow extent in order to force space allocation
5420 status = UDFResizeExtent(Vcb, PartNum, Vcb->LBlockSize, FALSE, &Dloc->DataLoc);
5421 if(!OS_SUCCESS(status)) {
5422 MyFreePool__(OldInIcb);
5423 return status;
5424 }
5425
5426 // set Alloc mode
5427 if((((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK) == ICB_FLAG_AD_IN_ICB) {
5428 ((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags &= ~ICB_FLAG_ALLOC_MASK;
5429 ((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags |= NewAllocMode;
5430 } else {
5431 BrutePoint();
5432 }
5433
5434 // revert to initial extent size. This will not cause NonInICB->InICB transform
5435 status = UDFResizeExtent(Vcb, PartNum, OldLen, FALSE, &Dloc->DataLoc);
5436 if(!OS_SUCCESS(status)) {
5437 MyFreePool__(OldInIcb);
5438 return status;
5439 }
5440
5441 // replace data from ICB (if any) & free buffer
5442 status = UDFWriteExtent(Vcb, &(Dloc->DataLoc), 0, OldLen, FALSE, OldInIcb, &_WrittenBytes);
5443 MyFreePool__(OldInIcb);
5444 if(!OS_SUCCESS(status)) {
5445 return status;
5446 }
5447 // inform UdfInfo, that AllocDesc's must be rebuilt on flush/close
5448 Dloc->AllocLoc.Modified = TRUE;
5449 Dloc->DataLoc.Modified = TRUE;
5450 return STATUS_SUCCESS;
5451} // end UDFConvertFEToNonInICB()
5452
5453/*
5454 This routine converts file's FE to extended form.
5455 It is needed for stream creation.
5456 */
5459 IN PVCB Vcb,
5461 )
5462{
5463 PEXTENDED_FILE_ENTRY ExFileEntry;
5464 PFILE_ENTRY FileEntry;
5468
5471 if(FileInfo->Dloc->FileEntry->tagIdent == TID_EXTENDED_FILE_ENTRY) return STATUS_SUCCESS;
5472 if(FileInfo->Dloc->FileEntry->tagIdent != TID_FILE_ENTRY) return STATUS_INVALID_PARAMETER;
5473
5474/* if(!OS_SUCCESS(status = UDFFlushFile__(Vcb, FileInfo)))
5475 return status;*/
5476
5477 Length = FileInfo->Dloc->FileEntryLen;
5478 NewLength = Length - sizeof(FILE_ENTRY) + sizeof(EXTENDED_FILE_ENTRY);
5480 if(!ExFileEntry) return STATUS_INSUFFICIENT_RESOURCES;
5481 FileEntry = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
5482 RtlZeroMemory(ExFileEntry, NewLength);
5483
5485 ExFileEntry->icbTag = FileEntry->icbTag;
5486 ExFileEntry->uid = FileEntry->uid;
5487 ExFileEntry->gid = FileEntry->gid;
5488 ExFileEntry->permissions = FileEntry->permissions;
5489 ExFileEntry->fileLinkCount = FileEntry->fileLinkCount;
5490 ExFileEntry->recordFormat = FileEntry->recordFormat;
5491 ExFileEntry->recordDisplayAttr = FileEntry->recordDisplayAttr;
5492 ExFileEntry->recordLength = FileEntry->recordLength;
5493 ExFileEntry->informationLength = FileEntry->informationLength;
5494 ExFileEntry->logicalBlocksRecorded = FileEntry->logicalBlocksRecorded;
5495 ExFileEntry->accessTime = FileEntry->accessTime;
5496 ExFileEntry->modificationTime = FileEntry->modificationTime;
5497 ExFileEntry->attrTime = FileEntry->attrTime;
5498 ExFileEntry->checkpoint = FileEntry->checkpoint;
5499 ExFileEntry->extendedAttrICB = FileEntry->extendedAttrICB;
5500 ExFileEntry->impIdent = FileEntry->impIdent;
5501 ExFileEntry->uniqueID = FileEntry->uniqueID;
5502 ExFileEntry->lengthExtendedAttr = FileEntry->lengthExtendedAttr;
5503 ExFileEntry->lengthAllocDescs = FileEntry->lengthAllocDescs;
5504 RtlCopyMemory(ExFileEntry+1, FileEntry+1, FileEntry->lengthExtendedAttr);
5505 RtlCopyMemory((int8*)(ExFileEntry+1)+FileEntry->lengthExtendedAttr, (int8*)(ExFileEntry+1)+FileEntry->lengthExtendedAttr, FileEntry->lengthAllocDescs);
5506
5507 if((((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK) == ICB_FLAG_AD_IN_ICB) {
5508
5509 if((l = (uint32)(FileInfo->Dloc->DataLoc.Length))) {
5510
5511 int8* tmp_buff = (int8*)MyAllocatePool__(NonPagedPool, l);
5512 if(!tmp_buff) {
5513 MyFreePool__(ExFileEntry);
5515 }
5516 if(!OS_SUCCESS(status = UDFReadFile__(Vcb, FileInfo, 0, l, FALSE, tmp_buff, &ReadBytes)) ||
5518 MyFreePool__(ExFileEntry);
5519 MyFreePool__(tmp_buff);
5520 return status;
5521 }
5522 FileInfo->Dloc->FELoc.Length =
5523 FileInfo->Dloc->DataLoc.Offset = NewLength;
5524 FileInfo->Dloc->FELoc.Modified =
5525 FileInfo->Dloc->DataLoc.Modified = TRUE;
5526 MyFreePool__(FileInfo->Dloc->FileEntry);
5527 FileInfo->Dloc->FileEntry = (tag*)ExFileEntry;
5529 !OS_SUCCESS(status = UDFWriteFile__(Vcb, FileInfo, 0, l, FALSE, tmp_buff, &ReadBytes)) ) {
5530 MyFreePool__(ExFileEntry);
5531 MyFreePool__(tmp_buff);
5532 return status;
5533 }
5534 MyFreePool__(tmp_buff);
5535 } else {
5536 FileInfo->Dloc->FELoc.Length =
5537 FileInfo->Dloc->DataLoc.Offset = NewLength;
5538 FileInfo->Dloc->FELoc.Modified =
5539 FileInfo->Dloc->DataLoc.Modified = TRUE;
5540 MyFreePool__(FileInfo->Dloc->FileEntry);
5541 FileInfo->Dloc->FileEntry = (tag*)ExFileEntry;
5542 }
5543 } else {
5544 FileInfo->Dloc->FELoc.Length =
5545 FileInfo->Dloc->AllocLoc.Offset = NewLength;
5546 FileInfo->Dloc->FELoc.Modified =
5547 FileInfo->Dloc->AllocLoc.Modified = TRUE;
5548 MyFreePool__(FileInfo->Dloc->FileEntry);
5549 FileInfo->Dloc->FileEntry = (tag*)ExFileEntry;
5550 }
5551 FileInfo->Dloc->FileEntryLen = NewLength;
5552 FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
5553 if(Vcb->minUDFReadRev < 0x0200)
5554 Vcb->minUDFReadRev = 0x0200;
5555 return STATUS_SUCCESS;
5556} // end UDFConvertFEToExtended()
5557
5558/*
5559 This routine makes file almost unavailable for external callers.
5560 The only way to access Hidden with this routine file is OpenByIndex.
5561 It is usefull calling this routine to pretend file to be deleted,
5562 for ex. when we have UDFCleanUp__() or smth. like this in progress,
5563 but we want to create file with the same name.
5564 */
5567 IN PVCB Vcb,
5569 )
5570{
5571 AdPrint(("UDFPretendFileDeleted__:\n"));
5572
5573 NTSTATUS RC;
5575 if(!hDirNdx) return STATUS_CANNOT_DELETE;
5576 PDIR_INDEX_ITEM DirNdx = UDFDirIndex(hDirNdx, FileInfo->Index);
5577 if(!DirNdx) return STATUS_CANNOT_DELETE;
5578
5579
5580 // we can't hide file that is not marked as deleted
5582 if(!NT_SUCCESS(RC))
5583 return RC;
5584
5585 AdPrint(("UDFPretendFileDeleted__: set UDF_FI_FLAG_FI_INTERNAL\n"));
5586
5588 if(DirNdx->FName.Buffer) {
5589 MyFreePool__(DirNdx->FName.Buffer);
5590 DirNdx->FName.Buffer = NULL;
5591 DirNdx->FName.Length =
5592 DirNdx->FName.MaximumLength = 0;
5593 }
5594 return STATUS_SUCCESS;
5595} // end UDFPretendFileDeleted__()
5596#endif //UDF_READ_ONLY_BUILD
static USHORT USHORT * NewLength
unsigned char BOOLEAN
VOID UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry, IN ULONG NTAttr)
ULONG UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry)
NTSTATUS UDFDoesOSAllowFilePretendDeleted__(IN PUDF_FILE_INFO FileInfo)
NTSTATUS UDFDoesOSAllowFileToBeTargetForRename__(IN PUDF_FILE_INFO FileInfo)
void __fastcall UDFDOSNameOsNative(IN OUT PUNICODE_STRING DosName, IN PUNICODE_STRING UdfName, IN BOOLEAN KeepIntact)
uint32 __fastcall UDFPartLen(PVCB Vcb, uint32 PartNum)
Definition: alloc.cpp:265
uint32 __fastcall UDFPartStart(PVCB Vcb, uint32 PartNum)
Definition: alloc.cpp:222
uint32 UDFPhysLbaToPart(IN PVCB Vcb, IN uint32 PartNum, IN uint32 Addr)
Definition: alloc.cpp:46
uint32 __fastcall UDFGetPartNumByPhysLba(IN PVCB Vcb, IN uint32 Lba)
Definition: alloc.cpp:201
uint32 __fastcall UDFPartLbaToPhys(IN PVCB Vcb, IN lb_addr *Addr)
Definition: alloc.cpp:114
LONG NTSTATUS
Definition: precomp.h:26
unsigned short uint16
Definition: types.h:30
unsigned int uint32
Definition: types.h:32
unsigned char uint8
Definition: types.h:28
#define index(s, c)
Definition: various.h:29
PFOR_CONTEXT fc
Definition: for.c:57
struct _root root
r l[0]
Definition: byte_order.h:168
#define try_return(S)
Definition: cdprocs.h:2179
#define PACKETSIZE_UDF
Definition: cdrw_usr.h:1753
struct _VCB * PVCB
Definition: fatstruc.h:557
Definition: bufpool.h:45
static void xor(unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count)
Definition: crypt_des.c:251
#define Len
Definition: deflate.h:82
#define IgnoreCase
Definition: cdprocs.h:461
void UDFInsertLinkedFile(PUDF_FILE_INFO fi, PUDF_FILE_INFO fi2)
Definition: dirtree.cpp:1470
OSSTATUS UDFPackDirectory__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:743
OSSTATUS UDFStoreDloc(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN uint32 Lba)
Definition: dirtree.cpp:1240
OSSTATUS UDFReleaseDloc(IN PVCB Vcb, IN PUDF_DATALOC_INFO Dloc)
Definition: dirtree.cpp:1224
PUDF_FILE_INFO UDFLocateAnyParallelFI(PUDF_FILE_INFO fi)
Definition: dirtree.cpp:1439
OSSTATUS UDFRemoveDloc(IN PVCB Vcb, IN PUDF_DATALOC_INFO Dloc)
Definition: dirtree.cpp:1299
OSSTATUS UDFIndexDirectory(IN PVCB Vcb, IN OUT PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:507
void UDFRelocateDloc(IN PVCB Vcb, IN PUDF_DATALOC_INFO Dloc, IN uint32 NewLba)
Definition: dirtree.cpp:1374
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
OSSTATUS UDFUnlinkDloc(IN PVCB Vcb, IN PUDF_DATALOC_INFO Dloc)
Definition: dirtree.cpp:1327
OSSTATUS UDFDirIndexGrow(IN PDIR_INDEX_HDR *_hDirNdx, IN uint_di d)
Definition: dirtree.cpp:117
void UDFDirIndexFree(PDIR_INDEX_HDR hDirNdx)
Definition: dirtree.cpp:98
PDIR_INDEX_ITEM UDFDirIndexScan(PUDF_DIR_SCAN_CONTEXT Context, PUDF_FILE_INFO *_FileInfo)
Definition: dirtree.cpp:378
PUDF_FILE_INFO UDFLocateParallelFI(PUDF_FILE_INFO di, uint_di i, PUDF_FILE_INFO fi)
Definition: dirtree.cpp:1417
uint8 UDFBuildHashEntry(IN PVCB Vcb, IN PUNICODE_STRING Name, OUT PHASH_ENTRY hashes, IN uint8 Mask)
Definition: dirtree.cpp:429
OSSTATUS UDFReTagDirectory(IN PVCB Vcb, IN OUT PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:895
OSSTATUS UDFFindFile(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN BOOLEAN NotDeleted, IN PUNICODE_STRING Name, IN PUDF_FILE_INFO DirInfo, IN OUT uint_di *Index)
Definition: dirtree.cpp:982
LONG UDFFindDloc(IN PVCB Vcb, IN uint32 Lba)
Definition: dirtree.cpp:1127
BOOLEAN UDFDirIndexInitScan(IN PUDF_FILE_INFO DirInfo, OUT PUDF_DIR_SCAN_CONTEXT Context, IN uint_di Index)
Definition: dirtree.cpp:347
void UDFFreeDloc(IN PVCB Vcb, IN PUDF_DATALOC_INFO Dloc)
Definition: dirtree.cpp:1353
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
#define crc32(crc, buf, len)
Definition: inflate.c:1081
static const WCHAR *const ext[]
Definition: module.c:53
static const WCHAR Linked[]
Definition: interface.c:30
void Replace(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LONG radius)
Definition: drawing.cpp:132
ULONG to_read
Definition: btrfs.c:4260
unsigned long long uint64
Definition: platform.h:18
short int16
Definition: platform.h:11
long int32
Definition: platform.h:12
char int8
Definition: platform.h:10
long long int64
Definition: platform.h:13
static NTSTATUS ReadBytes(IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
Definition: detect.c:67
struct _EXTENDED_FILE_ENTRY EXTENDED_FILE_ENTRY
#define FILE_PARENT
Definition: ecma_167.h:441
PEXTENT_AD PEXTENT_MAP
Definition: ecma_167.h:135
#define FILE_DIRECTORY
Definition: ecma_167.h:439
#define ICB_FLAG_AD_LONG
Definition: ecma_167.h:494
long_ad LONG_AD
Definition: ecma_167.h:379
struct _FILE_IDENT_DESC * PFILE_IDENT_DESC
#define TID_EXTENDED_FILE_ENTRY
Definition: ecma_167.h:175
struct _FILE_IDENT_DESC FILE_IDENT_DESC
struct _SHORT_AD SHORT_AD
#define UDF_FILE_TYPE_DIRECTORY
Definition: ecma_167.h:468
#define ICB_FLAG_AD_SHORT
Definition: ecma_167.h:493
#define UDF_FILE_TYPE_STREAMDIR
Definition: ecma_167.h:477
#define UDF_COMP_ID_16
Definition: ecma_167.h:23
#define EXTENT_NOT_RECORDED_NOT_ALLOCATED
Definition: ecma_167.h:369
#define TID_FILE_ENTRY
Definition: ecma_167.h:170
#define FILE_DELETED
Definition: ecma_167.h:440
#define UDF_FILE_TYPE_REGULAR
Definition: ecma_167.h:469
struct _EXTENDED_FILE_ENTRY * PEXTENDED_FILE_ENTRY
struct _FILE_ENTRY * PFILE_ENTRY
#define TID_FILE_IDENT_DESC
Definition: ecma_167.h:166
#define ICB_FLAG_AD_IN_ICB
Definition: ecma_167.h:496
#define ICB_FLAG_ALLOC_MASK
Definition: ecma_167.h:480
#define UDF_COMP_ID_8
Definition: ecma_167.h:22
#define ICB_FLAG_AD_EXTENDED
Definition: ecma_167.h:495
EXTENT_AD EXTENT_MAP
Definition: ecma_167.h:134
__declspec(noinline) int TestFunc(int
Definition: ehthrow.cxx:232
static PVOID Mapping[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:41
#define ValidateFileInfo(fi)
Definition: env_spec_w32.h:516
#define OS_SUCCESS(a)
Definition: env_spec_w32.h:56
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define ExtPrint(_x_)
Definition: env_spec_w32.h:294
#define DbgFreePool
Definition: env_spec_w32.h:334
#define UDFInterlockedDecrement(addr)
Definition: env_spec_w32.h:677
#define OSSTATUS
Definition: env_spec_w32.h:57
#define DbgAllocatePool
Definition: env_spec_w32.h:332
#define NonPagedPool
Definition: env_spec_w32.h:307
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
#define BrutePoint()
Definition: env_spec_w32.h:504
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
#define PagedPool
Definition: env_spec_w32.h:308
#define UID
Definition: ext2fs.h:154
OSSTATUS UDFBuildAllocDescs(IN PVCB Vcb, IN uint32 PartNum, IN OUT PUDF_FILE_INFO FileInfo, OUT int8 **AllocData)
Definition: extent.cpp:2628
int64 UDFGetExtentLength(IN PEXTENT_MAP Extent)
Definition: extent.cpp:142
OSSTATUS __fastcall UDFUnPackMapping(IN PVCB Vcb, IN PEXTENT_INFO ExtInfo)
Definition: extent.cpp:2860
OSSTATUS UDFReadExtent(IN PVCB Vcb, IN PEXTENT_INFO ExtInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, OUT int8 *Buffer, OUT PSIZE_T ReadBytes)
Definition: extent.cpp:3021
OSSTATUS UDFAllocateFESpace(IN PVCB Vcb, IN PUDF_FILE_INFO DirInfo, IN uint32 PartNum, IN PEXTENT_INFO FEExtInfo, IN uint32 Len)
Definition: extent.cpp:1563
void UDFFlushFESpace(IN PVCB Vcb, IN PUDF_DATALOC_INFO Dloc, IN BOOLEAN Discard)
Definition: extent.cpp:1776
uint32 UDFExtentOffsetToLba(IN PVCB Vcb, IN PEXTENT_MAP Extent, IN int64 Offset, OUT uint32 *SectorOffset, OUT PSIZE_T AvailLength, OUT uint32 *Flags, OUT uint32 *Index)
Definition: extent.cpp:28
void __fastcall UDFPackMapping(IN PVCB Vcb, IN PEXTENT_INFO ExtInfo)
Definition: extent.cpp:2747
void UDFFreeFESpace(IN PVCB Vcb, IN PUDF_FILE_INFO DirInfo, IN PEXTENT_INFO FEExtInfo)
Definition: extent.cpp:1725
PEXTENT_MAP UDFReadMappingFromXEntry(IN PVCB Vcb, IN uint32 PartNum, IN tag *XEntry, IN OUT uint32 *Offset, OUT PEXTENT_INFO AllocLoc)
Definition: extent.cpp:735
OSSTATUS UDFResizeExtent(IN PVCB Vcb, IN uint32 PartNum, IN int64 Length, IN BOOLEAN AlwaysInIcb, OUT PEXTENT_INFO ExtInfo)
Definition: extent.cpp:2235
void UDFFreeFileAllocation(IN PVCB Vcb, IN PUDF_FILE_INFO DirInfo, IN PUDF_FILE_INFO FileInfo)
Definition: extent.cpp:2696
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
uint32 UDFGetMappingLength(IN PEXTENT_MAP Extent)
Definition: extent.cpp:223
static unsigned char buff[32768]
Definition: fatten.c:17
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble n
Definition: glext.h:7729
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define NOTHING
Definition: input_list.c:10
const WCHAR * word
Definition: lex.c:36
#define d
Definition: ke_i.h:81
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define MyFreePool__(addr)
Definition: mem_tools.h:152
ULONG MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen)
Definition: mem_tools.h:230
#define MyAllocatePoolTag__(type, size, tag)
Definition: mem_tools.h:150
#define ASSERT(a)
Definition: mode.c:44
struct task_struct * current
Definition: linux.c:32
static PVOID ptr
Definition: dispmode.c:27
#define __fastcall
Definition: sync.c:38
static const WCHAR tb[]
Definition: suminfo.c:285
#define min(a, b)
Definition: monoChain.cc:55
WCHAR * PWCH
Definition: ntbasedef.h:410
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
#define ENTITYID_FLAGS_SOFT_RO
Definition: osta_misc.h:223
#define UDF_ID_DEVELOPER
Definition: osta_misc.h:20
#define UDF_VAT_FREE_ENTRY
Definition: osta_misc.h:71
#define UDF_ID_ALLOC
Definition: osta_misc.h:278
#define UDF_EXTENT_LENGTH_MASK
Definition: osta_misc.h:148
#define UDF_VIRTUAL_MAP20
Definition: osta_misc.h:94
#define UDF_OS_ID_WINNT
Definition: osta_misc.h:300
#define UDF_OS_CLASS_WINNT
Definition: osta_misc.h:288
#define ENTITYID_FLAGS_HARD_RO
Definition: osta_misc.h:222
#define UDF_VIRTUAL_MAP15
Definition: osta_misc.h:93
#define UDF_FILE_TYPE_VAT15
Definition: osta_misc.h:159
#define UDF_NAME_LEN
Definition: osta_misc.h:314
#define UDF_FILE_TYPE_VAT20
Definition: osta_misc.h:171
long LONG
Definition: pedump.c:60
#define Vcb
Definition: cdprocs.h:1415
OSSTATUS UDFWriteData(IN PVCB Vcb, IN BOOLEAN Translate, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, IN int8 *Buffer, OUT PSIZE_T WrittenBytes)
Definition: phys_lib.cpp:4141
#define UDFReadSectors(Vcb, Translate, Lba, BCount, Direct, Buffer, ReadBytes)
Definition: phys_lib.h:126
#define UDFRemoveFileId__(Vcb, fi)
Definition: protos.h:407
_Out_opt_ int * cx
Definition: commctrl.h:585
static calc_node_t * pop(void)
Definition: rpn_ieee.c:90
static void push(calc_node_t *op)
Definition: rpn_ieee.c:113
#define New(t)
Definition: rtf.h:1086
#define f2(x, y, z)
Definition: sha1.c:31
#define f1(x, y, z)
Definition: sha1.c:30
#define rol(value, bits)
Definition: sha1.c:24
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
uint8 ident[23]
Definition: ecma_167.h:61
uint8 identSuffix[8]
Definition: ecma_167.h:62
uint8 flags
Definition: ecma_167.h:60
Definition: shlfileop.cpp:53
#define UDF_FLUSH_FLAGS_LITE
Definition: struct.h:341
uint_di DelCount
Definition: udf_rel.h:139
UNICODE_STRING FName
Definition: udf_rel.h:173
int64 AllocationSize
Definition: udf_rel.h:214
struct _UDF_FILE_INFO * FileInfo
Definition: udf_rel.h:204
uint8 FI_Flags
Definition: udf_rel.h:199
uint32 Offset
Definition: udf_rel.h:161
lb_addr FileEntryLoc
Definition: udf_rel.h:178
uint8 FileCharacteristics
Definition: udf_rel.h:182
uint32 Length
Definition: udf_rel.h:168
int64 FileSize
Definition: udf_rel.h:213
HASH_ENTRY hashes
Definition: udf_rel.h:206
Definition: ecma_167.h:742
icbtag icbTag
Definition: ecma_167.h:744
uint64 informationLength
Definition: ecma_167.h:752
timestamp modificationTime
Definition: ecma_167.h:756
uint32 permissions
Definition: ecma_167.h:747
uint32 checkpoint
Definition: ecma_167.h:759
uint64 uniqueID
Definition: ecma_167.h:764
uint16 fileLinkCount
Definition: ecma_167.h:748
uint32 gid
Definition: ecma_167.h:746
long_ad extendedAttrICB
Definition: ecma_167.h:761
timestamp accessTime
Definition: ecma_167.h:755
uint64 logicalBlocksRecorded
Definition: ecma_167.h:754
uint32 lengthExtendedAttr
Definition: ecma_167.h:765
uint32 uid
Definition: ecma_167.h:745
timestamp attrTime
Definition: ecma_167.h:758
EntityID impIdent
Definition: ecma_167.h:763
uint8 recordFormat
Definition: ecma_167.h:749
uint32 recordLength
Definition: ecma_167.h:751
tag descTag
Definition: ecma_167.h:743
uint8 recordDisplayAttr
Definition: ecma_167.h:750
uint32 lengthAllocDescs
Definition: ecma_167.h:766
uint32 extLength
Definition: ecma_167.h:128
uint32 extLocation
Definition: ecma_167.h:129
PEXTENT_MAP Mapping
Definition: udf_rel.h:66
int64 Length
Definition: udf_rel.h:67
UCHAR Flags
Definition: udf_rel.h:69
BOOLEAN Modified
Definition: udf_rel.h:68
uint32 Offset
Definition: udf_rel.h:65
Definition: ecma_167.h:513
tag descTag
Definition: ecma_167.h:514
uint32 permissions
Definition: ecma_167.h:518
uint16 fileLinkCount
Definition: ecma_167.h:519
uint32 lengthAllocDescs
Definition: ecma_167.h:534
uint32 checkpoint
Definition: ecma_167.h:528
uint32 lengthExtendedAttr
Definition: ecma_167.h:533
uint32 gid
Definition: ecma_167.h:517
EntityID impIdent
Definition: ecma_167.h:530
uint8 recordDisplayAttr
Definition: ecma_167.h:521
timestamp modificationTime
Definition: ecma_167.h:526
uint64 logicalBlocksRecorded
Definition: ecma_167.h:524
uint64 uniqueID
Definition: ecma_167.h:531
timestamp accessTime
Definition: ecma_167.h:525
uint32 recordLength
Definition: ecma_167.h:522
uint64 informationLength
Definition: ecma_167.h:523
long_ad extendedAttrICB
Definition: ecma_167.h:529
icbtag icbTag
Definition: ecma_167.h:515
timestamp attrTime
Definition: ecma_167.h:527
uint8 recordFormat
Definition: ecma_167.h:520
uint32 uid
Definition: ecma_167.h:516
uint16 lengthOfImpUse
Definition: ecma_167.h:431
uint16 fileVersionNum
Definition: ecma_167.h:427
uint8 lengthFileIdent
Definition: ecma_167.h:429
uint8 fileCharacteristics
Definition: ecma_167.h:428
uint32 FE_Flags
Definition: udf_rel.h:299
struct _UDF_FILE_INFO * SDirInfo
Definition: udf_rel.h:319
EXTENT_INFO FELoc
Definition: udf_rel.h:279
EXTENT_INFO DataLoc
Definition: udf_rel.h:262
struct _UDFNTRequiredFCB * CommonFcb
Definition: udf_rel.h:255
uint32 LinkRefCount
Definition: udf_rel.h:306
EXTENT_INFO AllocLoc
Definition: udf_rel.h:274
PDIR_INDEX_HDR DirIndex
Definition: udf_rel.h:312
uint32 FileIdentLen
Definition: udf_rel.h:376
uint32 OpenCount
Definition: udf_rel.h:407
PUDF_DATALOC_INFO Dloc
Definition: udf_rel.h:367
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
uint32 RefCount
Definition: udf_rel.h:399
struct _UDF_FILE_INFO * ParentFile
Definition: udf_rel.h:381
uint_di Index
Definition: udf_rel.h:392
PFILE_IDENT_DESC FileIdent
Definition: udf_rel.h:372
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cdstruc.h:498
uint16 numEntries
Definition: ecma_167.h:456
uint8 fileType
Definition: ecma_167.h:458
uint16 strategyType
Definition: ecma_167.h:454
uint16 flags
Definition: ecma_167.h:460
uint16 partitionReferenceNum
Definition: ecma_167.h:363
uint32 logicalBlockNum
Definition: ecma_167.h:362
lb_addr extLocation
Definition: ecma_167.h:375
uint32 extLength
Definition: ecma_167.h:374
uint8 impUse[6]
Definition: ecma_167.h:376
Definition: ps.c:97
Definition: ecma_167.h:138
uint8 tagChecksum
Definition: ecma_167.h:141
uint16 descVersion
Definition: ecma_167.h:140
uint32 tagLocation
Definition: ecma_167.h:146
uint16 descCRCLength
Definition: ecma_167.h:145
uint16 descCRC
Definition: ecma_167.h:144
uint16 tagIdent
Definition: ecma_167.h:139
#define max(a, b)
Definition: svc.c:63
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl ebx
Definition: synth_sse3d.h:83
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx shrl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm0 paddd mm4 psrad mm0 psrad mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx andl ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm0 psrad mm0 packssdw mm0 movd eax movw edi esi edx edi
Definition: synth_sse3d.h:185
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx shrl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm0 paddd mm4 psrad mm0 psrad mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx andl ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm0 psrad mm0 packssdw mm0 movd eax movw ax
Definition: synth_sse3d.h:180
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl eax
Definition: synth_sse3d.h:85
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esi
Definition: synth_sse3d.h:103
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx
Definition: synth_sse3d.h:87
#define BS
Definition: telnetd.h:22
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define UDF_VCB_IC_HW_RO
Definition: udf_common.h:502
#define UDF_VCB_IC_OS_NATIVE_DOS_NAME
Definition: udf_common.h:503
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS
Definition: udf_common.h:501
#define UDF_VCB_FLAGS_MEDIA_READ_ONLY
Definition: udf_common.h:481
#define UDF_VCB_IC_SOFT_RO
Definition: udf_common.h:514
OSSTATUS UDFHardLinkFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN OUT BOOLEAN *Replace, IN PUNICODE_STRING fn, IN OUT PUDF_FILE_INFO DirInfo1, IN OUT PUDF_FILE_INFO DirInfo2, IN OUT PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:4672
int64 UDFGetFileUID(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1509
void UDFSetFileSize(IN PUDF_FILE_INFO FileInfo, IN int64 Size)
Definition: udf_info.cpp:1157
void UDFSetUpTag(IN PVCB Vcb, IN tag *Tag, IN uint16 DataLen, IN uint32 TagLoc)
Definition: udf_info.cpp:936
OSSTATUS UDFBuildFileEntry(IN PVCB Vcb, IN PUDF_FILE_INFO DirInfo, IN PUDF_FILE_INFO FileInfo, IN uint32 PartNum, IN uint16 AllocMode, IN uint32 ExtAttrSz, IN BOOLEAN Extended)
Definition: udf_info.cpp:971
OSSTATUS UDFRenameMoveFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN OUT BOOLEAN *Replace, IN PUNICODE_STRING fn, IN OUT PUDF_FILE_INFO DirInfo1, IN OUT PUDF_FILE_INFO DirInfo2, IN OUT PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:3176
static const char crcChar[]
Definition: udf_info.cpp:46
uint16 UDFGetFileLinkCount(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1355
OSSTATUS UDFConvertFEToExtended(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:5458
uint32 UDFGetFileEALength(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1420
void __fastcall UDFDOSName100(IN OUT PUNICODE_STRING DosName, IN PUNICODE_STRING UdfName, IN BOOLEAN KeepIntact)
Definition: udf_info.cpp:465
OSSTATUS UDFOpenRootFile__(IN PVCB Vcb, IN lb_addr *RootLoc, OUT PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2187
uint16 __fastcall UDFUnicodeCksum(PWCHAR s, uint32 n)
Definition: udf_info.cpp:4356
OSSTATUS UDFRecordDirectory__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO DirInfo)
Definition: udf_info.cpp:3384
OSSTATUS UDFWriteFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, IN int8 *Buffer, OUT PSIZE_T WrittenBytes)
Definition: udf_info.cpp:1605
uint16 __fastcall UDFCrc(IN uint8 *Data, IN SIZE_T Size)
Definition: udf_info.cpp:4527
#define hexChar
Definition: udf_info.cpp:45
__inline int64 UDFGetFileUID_(IN tag *FileEntry)
Definition: udf_info.cpp:1491
void __fastcall UDFDOSName200(IN OUT PUNICODE_STRING DosName, IN PUNICODE_STRING UdfName, IN BOOLEAN KeepIntact, IN BOOLEAN Mode150)
Definition: udf_info.cpp:582
uint16 __fastcall UDFUnicodeCksum150(PWCHAR s, uint32 n)
Definition: udf_info.cpp:4422
OSSTATUS UDFPadLastSector(IN PVCB Vcb, IN PEXTENT_INFO ExtInfo)
Definition: udf_info.cpp:2962
OSSTATUS UDFUpdateVAT(IN void *_Vcb, IN uint32 Lba, IN uint32 *RelocTab, IN uint32 BCount)
Definition: udf_info.cpp:5316
void __fastcall UDFCompressUnicode(IN PUNICODE_STRING UName, IN OUT uint8 **_CS0, IN OUT PSIZE_T Length)
Definition: udf_info.cpp:240
OSSTATUS UDFFlushFI(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN uint32 PartNum)
Definition: udf_info.cpp:4051
int64 UDFGetFileSize(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1236
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
OSSTATUS UDFBuildFileIdent(IN PVCB Vcb, IN PUNICODE_STRING fn, IN PLONG_AD FileEntryIcb, IN uint32 ImpUseLen, OUT PFILE_IDENT_DESC *_FileId, OUT uint32 *FileIdLen)
Definition: udf_info.cpp:1107
BOOLEAN __fastcall UDFIsIllegalChar(IN WCHAR chr)
Definition: udf_info.cpp:370
OSSTATUS UDFFlushFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN ULONG FlushFlags)
Definition: udf_info.cpp:4119
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
#define DOS_CRC_MODULUS
Definition: udf_info.cpp:44
OSSTATUS UDFUnlinkFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN FreeSpace)
Definition: udf_info.cpp:1766
void __fastcall UDFDOSName(IN PVCB Vcb, IN OUT PUNICODE_STRING DosName, IN PUNICODE_STRING UdfName, IN BOOLEAN KeepIntact)
Definition: udf_info.cpp:427
void UDFChangeFileCounter(IN PVCB Vcb, IN BOOLEAN FileCounter, IN BOOLEAN Increase)
Definition: udf_info.cpp:1520
static const uint32 crc32_tab[]
Definition: udf_info.cpp:86
OSSTATUS UDFOpenStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4965
void UDFSetFileUID(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1456
void UDFReadEntityID_Domain(PVCB Vcb, EntityID *eID)
Definition: udf_info.cpp:1559
#define DOS_CRC_LEN
BOOLEAN UDFUnicodeInString(IN uint8 *string, IN WCHAR ch)
Definition: udf_info.cpp:336
BOOLEAN UDFIsDirEmpty(IN PDIR_INDEX_HDR hCurDirNdx)
Definition: udf_info.cpp:3844
OSSTATUS UDFReadTagged(PVCB Vcb, int8 *Buf, uint32 Block, uint32 Location, uint16 *Ident)
Definition: udf_info.cpp:4586
OSSTATUS UDFCreateRootFile__(IN PVCB Vcb, IN uint32 PartNum, IN uint32 ExtAttrSz, IN uint32 ImpUseLen, IN BOOLEAN Extended, OUT PUDF_FILE_INFO *_FileInfo)
Definition: udf_info.cpp:4827
void UDFSetEntityID_imp_(IN EntityID *eID, IN uint8 *Str, IN uint32 Len)
Definition: udf_info.cpp:1542
void UDFSetFileSizeInDirNdx(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 *ASize)
Definition: udf_info.cpp:1190
int64 UDFGetFileSizeFromDirNdx(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1256
OSSTATUS UDFResizeFile__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO FileInfo, IN int64 NewLength)
Definition: udf_info.cpp:3468
static const uint16 CrcTable[256]
Definition: udf_info.cpp:51
OSSTATUS UDFLoadVAT(IN PVCB Vcb, IN uint32 PartNdx)
Definition: udf_info.cpp:3602
static const char valid_char_arr[]
Definition: udf_info.cpp:41
OSSTATUS UDFConvertFEToNonInICB(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN uint8 NewAllocMode)
Definition: udf_info.cpp:5358
OSSTATUS UDFRecordVAT(IN PVCB Vcb)
Definition: udf_info.cpp:5036
void __fastcall UDFDecompressUnicode(IN OUT PUNICODE_STRING UName, IN uint8 *CS0, IN SIZE_T Length, OUT uint16 *valueCRC)
Definition: udf_info.cpp:170
__inline OSSTATUS UDFSparseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, OUT PSIZE_T ReadBytes)
Definition: udf_info.cpp:2944
OSSTATUS UDFReadFileEntry(IN PVCB Vcb, IN long_ad *Icb, IN OUT PFILE_ENTRY FileEntry, IN OUT uint16 *Ident)
Definition: udf_info.cpp:306
OSSTATUS UDFLoadExtInfo(IN PVCB Vcb, IN PFILE_ENTRY fe, IN PLONG_AD fe_loc, IN OUT PEXTENT_INFO FExtInfo, IN OUT PEXTENT_INFO AExtInfo)
Definition: udf_info.cpp:1062
void UDFSetAllocDescLen(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1277
OSSTATUS UDFUnlinkAllFilesInDir(IN PVCB Vcb, IN PUDF_FILE_INFO DirInfo)
Definition: udf_info.cpp:1945
BOOLEAN UDFCompareFileInfo(IN PUDF_FILE_INFO f1, IN PUDF_FILE_INFO f2)
Definition: udf_info.cpp:4218
__inline OSSTATUS UDFZeroFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, OUT PSIZE_T ReadBytes)
Definition: udf_info.cpp:2925
OSSTATUS UDFPretendFileDeleted__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:5566
#define lba
OSSTATUS UDFCreateFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN PUNICODE_STRING _fn, IN uint32 ExtAttrSz, IN uint32 ImpUseLen, IN BOOLEAN Extended, IN BOOLEAN CreateNew, IN OUT PUDF_FILE_INFO DirInfo, OUT PUDF_FILE_INFO *_FileInfo)
Definition: udf_info.cpp:2577
OSSTATUS UDFCreateStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4888
int64 UDFAssingNewFUID(IN PVCB Vcb)
Definition: udf_info.cpp:1445
OSSTATUS UDFOpenFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN BOOLEAN NotDeleted, IN PUNICODE_STRING fn, IN PUDF_FILE_INFO DirInfo, OUT PUDF_FILE_INFO *_FileInfo, IN uint_di *IndexToOpen)
Definition: udf_info.cpp:2004
OSSTATUS UDFFlushFE(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN uint32 PartNum)
Definition: udf_info.cpp:3864
void UDFChangeFileLinkCount(IN PUDF_FILE_INFO FileInfo, IN BOOLEAN Increase)
Definition: udf_info.cpp:1315
void __fastcall UDFDOSName201(IN OUT PUNICODE_STRING DosName, IN PUNICODE_STRING UdfName, IN BOOLEAN KeepIntact)
Definition: udf_info.cpp:700
#define UDFDecFileLinkCount(fi)
Definition: udf_info.h:581
#define UDFIncFileLinkCount(fi)
Definition: udf_info.h:580
#define UDFSetEntityID_imp(eID, Str)
Definition: udf_info.h:598
#define UDFIsSDirDeleted(FI)
Definition: udf_info.h:1004
#define AS_USED
Definition: udf_info.h:327
#define UDFStreamsSupported(Vcb)
Definition: udf_info.h:1037
#define FLUSH_FE_FOR_DEL
Definition: udf_info.h:396
#define UDF_FREE_NOTHING
Definition: udf_info.h:648
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
#define UDFHasAStreamDir(FI)
Definition: udf_info.h:1000
#define AS_FREE
Definition: udf_info.h:326
#define UDFIsDeleted(DirNdx)
Definition: udf_info.h:788
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
#define UDFGetPartNumByPartNdx(Vcb, pi)
Definition: udf_info.h:1028
#define UDFExtentToMapping(e)
Definition: udf_info.h:181
#define UDFIncFileCounter(Vcb)
Definition: udf_info.h:614
#define UDFIsAStreamDir(FI)
Definition: udf_info.h:998
#define UDFSetFreeBit(arr, bit)
Definition: udf_info.h:1201
#define UDFSetUsedBit(arr, bit)
Definition: udf_info.h:1200
#define UDFDirIndexGetLastIndex(di)
Definition: udf_info.h:1122
#define UDFDecDirCounter(Vcb)
Definition: udf_info.h:617
#define UDFSparseExtent__(Vcb, Ext, Off, Len, Dir, WB)
Definition: udf_info.h:542
#define UDFIncDirCounter(Vcb)
Definition: udf_info.h:616
#define UDFDecFileCounter(Vcb)
Definition: udf_info.h:615
#define UDF_FREE_FILEINFO
Definition: udf_info.h:649
#define UDFIsADirectory(FileInfo)
Definition: udf_info.h:792
#define UDFGetFreeBit(arr, bit)
Definition: udf_info.h:1199
__inline OSSTATUS UDFReadFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, OUT int8 *Buffer, OUT PSIZE_T ReadBytes)
Definition: udf_info.h:666
#define UDF_FREE_DLOC
Definition: udf_info.h:650
#define UDFGetBadBit(arr, bit)
Definition: udf_info.h:1205
#define UDFCheckSpaceAllocation(Vcb, FileInfo, Map, asXXX)
Definition: udf_info.h:281
#define AS_BAD
Definition: udf_info.h:329
#define UDFZeroExtent__(Vcb, Ext, Off, Len, Dir, WB)
Definition: udf_info.h:539
#define AS_DISCARDED
Definition: udf_info.h:328
#define UDFMarkSpaceAsXXX(Vcb, FileInfo, Map, asXXX)
Definition: udf_info.h:322
#define HASH_ALL
Definition: udf_info.h:78
#define MEM_FE_TAG
Definition: udf_rel.h:486
#define UDF_MAX_LINK_COUNT
Definition: udf_rel.h:509
#define MEM_FNAME_TAG
Definition: udf_rel.h:483
#define UNICODE_SPACE
Definition: udf_rel.h:424
#define DOS_NAME_LEN
Definition: udf_rel.h:419
#define MEM_FNAME16_TAG
Definition: udf_rel.h:484
#define EXTENT_FLAG_CUT_PREALLOCATED
Definition: udf_rel.h:80
uint32 uint_di
Definition: udf_rel.h:29
#define MEM_EXTMAP_TAG
Definition: udf_rel.h:492
#define MEM_FINF_TAG
Definition: udf_rel.h:489
#define UNICODE_PERIOD
Definition: udf_rel.h:423
#define UDF_FE_FLAG_IS_DEL_SDIR
File is Deleted Stream Dir.
Definition: udf_rel.h:333
#define UDF_FI_FLAG_FI_INTERNAL
Given entry represents the file used for internal FS purposes & must be invisible.
Definition: udf_rel.h:221
#define UDF_FE_FLAG_FE_MODIFIED
Was modified & should be flushed.
Definition: udf_rel.h:323
#define UDF_FE_FLAG_IS_SDIR
File is a StreamDir.
Definition: udf_rel.h:327
#define EXTENT_FLAG_VERIFY
Definition: udf_rel.h:81
#define MEM_VATFINF_TAG
Definition: udf_rel.h:490
#define UDF_FI_FLAG_FI_MODIFIED
FileIdent was modified & should be flushed.
Definition: udf_rel.h:217
#define UDF_FE_FLAG_HAS_DEL_SDIR
File contains pointer to Deleted Stream Dir.
Definition: udf_rel.h:331
#define ILLEGAL_CHAR_MARK
Definition: udf_rel.h:421
#define VRS_NSR03_FOUND
Definition: udf_rel.h:113
#define EXTENT_FLAG_PREALLOCATED
Definition: udf_rel.h:79
#define MEM_FID_TAG
Definition: udf_rel.h:488
#define MEM_XFE_TAG
Definition: udf_rel.h:487
#define UNICODE_CRC_MARK
Definition: udf_rel.h:422
#define MEM_FNAMECPY_TAG
Definition: udf_rel.h:485
#define UDF_FILE_INFO_MT
Definition: udf_rel.h:338
#define MEM_SDFINF_TAG
Definition: udf_rel.h:491
#define UDF_FILENAME_MT
Definition: udf_rel.h:126
#define LBA_OUT_OF_EXTENT
Definition: udf_rel.h:426
#define ICB_FLAG_AD_DEFAULT_ALLOC_MODE
Definition: udf_rel.h:506
#define UDF_INVALID_LINK_COUNT
Definition: udf_rel.h:508
#define UDF_FI_FLAG_LINKED
Related FileEntry has more than one FileIdent. It happends when we use HardLinks.
Definition: udf_rel.h:223
struct _UDF_FILE_INFO * PUDF_FILE_INFO
#define DOS_EXT_LEN
Definition: udf_rel.h:420
#define EXTENT_FLAG_ALLOC_SEQUENTIAL
Definition: udf_rel.h:77
#define UDF_FE_FLAG_HAS_SDIR
File contains Stream Dir.
Definition: udf_rel.h:325
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_TOO_MANY_LINKS
Definition: udferr_usr.h:184
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_SHARING_PAUSED
Definition: udferr_usr.h:165
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
#define STATUS_CRC_ERROR
Definition: udferr_usr.h:153
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define UDFInterlockedExchangeAdd(addr, i)
Definition: udffs.h:255
#define UDFPrint(Args)
Definition: udffs.h:223
#define UDF_USER_FS_FLAGS_HW_RO
Definition: udfpubl.h:113
#define UDF_USER_FS_FLAGS_SOFT_RO
Definition: udfpubl.h:112
VOID WCacheFlushAll__(IN PW_CACHE Cache, IN PVOID Context)
ULONG WCacheGetWriteBlockCount__(IN PW_CACHE Cache)
VOID WCacheSyncReloc__(IN PW_CACHE Cache, IN PVOID Context)
int ret
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_In_ WDFDEVICE _In_ WDF_SPECIAL_FILE_TYPE FileType
Definition: wdfdevice.h:2741
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1269
__wchar_t WCHAR
Definition: xmlstorage.h:180