1c2c66affSColin Finck ////////////////////////////////////////////////////////////////////
2c2c66affSColin Finck // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3c2c66affSColin Finck // All rights reserved
4c2c66affSColin Finck // This file was released under the GPLv2 on June 2015.
5c2c66affSColin Finck ////////////////////////////////////////////////////////////////////
6c2c66affSColin Finck /*************************************************************************
7c2c66affSColin Finck *
8c2c66affSColin Finck * File: Sys_Spec.cpp
9c2c66affSColin Finck *
10c2c66affSColin Finck * Module: UDF File System Driver
11c2c66affSColin Finck * (both User and Kernel mode execution)
12c2c66affSColin Finck *
13c2c66affSColin Finck * Description:
14c2c66affSColin Finck * Contains system-secific code
15c2c66affSColin Finck *
16c2c66affSColin Finck *************************************************************************/
17c2c66affSColin Finck
18c2c66affSColin Finck
19c2c66affSColin Finck /*
20c2c66affSColin Finck This routine converts UDF timestamp to NT time
21c2c66affSColin Finck */
22c2c66affSColin Finck LONGLONG
UDFTimeToNT(IN PUDF_TIME_STAMP UdfTime)23c2c66affSColin Finck UDFTimeToNT(
24c2c66affSColin Finck IN PUDF_TIME_STAMP UdfTime
25c2c66affSColin Finck )
26c2c66affSColin Finck {
27c2c66affSColin Finck LONGLONG NtTime;
28c2c66affSColin Finck TIME_FIELDS TimeFields;
29c2c66affSColin Finck
30c2c66affSColin Finck TimeFields.Milliseconds = (USHORT)(UdfTime->centiseconds * 10 + UdfTime->hundredsOfMicroseconds / 100);
31c2c66affSColin Finck TimeFields.Second = (USHORT)(UdfTime->second);
32c2c66affSColin Finck TimeFields.Minute = (USHORT)(UdfTime->minute);
33c2c66affSColin Finck TimeFields.Hour = (USHORT)(UdfTime->hour);
34c2c66affSColin Finck TimeFields.Day = (USHORT)(UdfTime->day);
35c2c66affSColin Finck TimeFields.Month = (USHORT)(UdfTime->month);
36c2c66affSColin Finck TimeFields.Year = (USHORT)((UdfTime->year < 1601) ? 1601 : UdfTime->year);
37c2c66affSColin Finck
38c2c66affSColin Finck if (!RtlTimeFieldsToTime(&TimeFields, (PLARGE_INTEGER)&NtTime)) {
39c2c66affSColin Finck NtTime = 0;
40c2c66affSColin Finck } else {
41c2c66affSColin Finck ExLocalTimeToSystemTime( (PLARGE_INTEGER)&NtTime, (PLARGE_INTEGER)&NtTime );
42c2c66affSColin Finck }
43c2c66affSColin Finck
44c2c66affSColin Finck return NtTime;
45c2c66affSColin Finck } // end UDFTimeToNT()
46c2c66affSColin Finck
47c2c66affSColin Finck
48c2c66affSColin Finck /*
49c2c66affSColin Finck This routine converts NT time to UDF timestamp
50c2c66affSColin Finck */
51c2c66affSColin Finck VOID
UDFTimeToUDF(IN LONGLONG NtTime,OUT PUDF_TIME_STAMP UdfTime)52c2c66affSColin Finck UDFTimeToUDF(
53c2c66affSColin Finck IN LONGLONG NtTime,
54c2c66affSColin Finck OUT PUDF_TIME_STAMP UdfTime
55c2c66affSColin Finck )
56c2c66affSColin Finck {
57c2c66affSColin Finck if(!NtTime) return;
58c2c66affSColin Finck LONGLONG LocalTime;
59c2c66affSColin Finck
60c2c66affSColin Finck TIME_FIELDS TimeFields;
61c2c66affSColin Finck
62c2c66affSColin Finck ExSystemTimeToLocalTime( (PLARGE_INTEGER)&NtTime, (PLARGE_INTEGER)&LocalTime );
63c2c66affSColin Finck RtlTimeToTimeFields( (PLARGE_INTEGER)&LocalTime, &TimeFields );
64c2c66affSColin Finck
65c2c66affSColin Finck LocalTime /= 10; // microseconds
66c2c66affSColin Finck UdfTime->microseconds = (UCHAR)(NtTime % 100);
67c2c66affSColin Finck LocalTime /= 100; // hundreds of microseconds
68c2c66affSColin Finck UdfTime->hundredsOfMicroseconds = (UCHAR)(NtTime % 100);
69c2c66affSColin Finck LocalTime /= 100; // centiseconds
70c2c66affSColin Finck UdfTime->centiseconds = (UCHAR)(TimeFields.Milliseconds / 10);
71c2c66affSColin Finck UdfTime->second = (UCHAR)(TimeFields.Second);
72c2c66affSColin Finck UdfTime->minute = (UCHAR)(TimeFields.Minute);
73c2c66affSColin Finck UdfTime->hour = (UCHAR)(TimeFields.Hour);
74c2c66affSColin Finck UdfTime->day = (UCHAR)(TimeFields.Day);
75c2c66affSColin Finck UdfTime->month = (UCHAR)(TimeFields.Month);
76c2c66affSColin Finck UdfTime->year = (USHORT)(TimeFields.Year);
77c2c66affSColin Finck UdfTime->typeAndTimezone = (TIMESTAMP_TYPE_LOCAL << 14);
78c2c66affSColin Finck } // end UDFTimeToUDF()
79c2c66affSColin Finck
80c2c66affSColin Finck /*
81c2c66affSColin Finck */
82c2c66affSColin Finck ULONG
UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx,IN tag * FileEntry)83c2c66affSColin Finck UDFAttributesToNT(
84c2c66affSColin Finck IN PDIR_INDEX_ITEM FileDirNdx,
85c2c66affSColin Finck IN tag* FileEntry
86c2c66affSColin Finck )
87c2c66affSColin Finck {
88c2c66affSColin Finck ASSERT(FileDirNdx);
89c2c66affSColin Finck if( (FileDirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) &&
90c2c66affSColin Finck !(FileDirNdx->FI_Flags & UDF_FI_FLAG_LINKED))
91c2c66affSColin Finck return FileDirNdx->SysAttr;
92c2c66affSColin Finck
93c2c66affSColin Finck ULONG NTAttr = 0;
94c2c66affSColin Finck ULONG attr = 0; //permissions
95c2c66affSColin Finck USHORT Flags = 0;
96c2c66affSColin Finck USHORT Type = 0;
97c2c66affSColin Finck UCHAR FCharact = 0;
98c2c66affSColin Finck
99c2c66affSColin Finck if(!FileEntry) {
100c2c66affSColin Finck if(!FileDirNdx->FileInfo)
101c2c66affSColin Finck return 0;
102c2c66affSColin Finck ValidateFileInfo(FileDirNdx->FileInfo);
103c2c66affSColin Finck FileEntry = FileDirNdx->FileInfo->Dloc->FileEntry;
104c2c66affSColin Finck }
105c2c66affSColin Finck if(FileEntry->tagIdent == TID_FILE_ENTRY) {
106c2c66affSColin Finck attr = ((PFILE_ENTRY)FileEntry)->permissions;
107c2c66affSColin Finck Flags = ((PFILE_ENTRY)FileEntry)->icbTag.flags;
108c2c66affSColin Finck Type = ((PFILE_ENTRY)FileEntry)->icbTag.fileType;
109c2c66affSColin Finck if(((PFILE_ENTRY)FileEntry)->fileLinkCount > 1)
110c2c66affSColin Finck FileDirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
111c2c66affSColin Finck } else {
112c2c66affSColin Finck attr = ((PEXTENDED_FILE_ENTRY)FileEntry)->permissions;
113c2c66affSColin Finck Flags = ((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.flags;
114c2c66affSColin Finck Type = ((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.fileType;
115c2c66affSColin Finck if(((PEXTENDED_FILE_ENTRY)FileEntry)->fileLinkCount > 1)
116c2c66affSColin Finck FileDirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
117c2c66affSColin Finck }
118c2c66affSColin Finck FCharact = FileDirNdx->FileCharacteristics;
119c2c66affSColin Finck
120c2c66affSColin Finck if(Flags & ICB_FLAG_SYSTEM) NTAttr |= FILE_ATTRIBUTE_SYSTEM;
121c2c66affSColin Finck if(Flags & ICB_FLAG_ARCHIVE) NTAttr |= FILE_ATTRIBUTE_ARCHIVE;
122c2c66affSColin Finck if((Type == UDF_FILE_TYPE_DIRECTORY) ||
123c2c66affSColin Finck (Type == UDF_FILE_TYPE_STREAMDIR) ||
124c2c66affSColin Finck (FCharact & FILE_DIRECTORY)) {
125c2c66affSColin Finck NTAttr |= FILE_ATTRIBUTE_DIRECTORY;
126c2c66affSColin Finck #ifdef UDF_DBG
127c2c66affSColin Finck } else {
128c2c66affSColin Finck //NTAttr |= FILE_ATTRIBUTE_NORMAL;
129c2c66affSColin Finck #endif
130c2c66affSColin Finck }
131c2c66affSColin Finck if(FCharact & FILE_HIDDEN) NTAttr |= FILE_ATTRIBUTE_HIDDEN;
132c2c66affSColin Finck if( !(attr & PERM_O_WRITE) &&
133c2c66affSColin Finck !(attr & PERM_G_WRITE) &&
134c2c66affSColin Finck !(attr & PERM_U_WRITE) &&
135c2c66affSColin Finck !(attr & PERM_O_DELETE) &&
136c2c66affSColin Finck !(attr & PERM_G_DELETE) &&
137c2c66affSColin Finck !(attr & PERM_U_DELETE) ) {
138c2c66affSColin Finck NTAttr |= FILE_ATTRIBUTE_READONLY;
139c2c66affSColin Finck }
140c2c66affSColin Finck FileDirNdx->SysAttr = NTAttr;
141c2c66affSColin Finck return NTAttr;
142c2c66affSColin Finck } // end UDFAttributesToNT()
143c2c66affSColin Finck
144c2c66affSColin Finck /*
145c2c66affSColin Finck */
146c2c66affSColin Finck VOID
UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx,IN tag * FileEntry,IN ULONG NTAttr)147c2c66affSColin Finck UDFAttributesToUDF(
148c2c66affSColin Finck IN PDIR_INDEX_ITEM FileDirNdx,
149c2c66affSColin Finck IN tag* FileEntry,
150c2c66affSColin Finck IN ULONG NTAttr
151c2c66affSColin Finck )
152c2c66affSColin Finck {
153c2c66affSColin Finck PULONG attr; //permissions
154c2c66affSColin Finck PUSHORT Flags;
155c2c66affSColin Finck PUCHAR Type;
156c2c66affSColin Finck PUCHAR FCharact;
157c2c66affSColin Finck
158c2c66affSColin Finck NTAttr &= UDF_VALID_FILE_ATTRIBUTES;
159c2c66affSColin Finck
160c2c66affSColin Finck if(!FileEntry) {
161c2c66affSColin Finck ASSERT(FileDirNdx);
162c2c66affSColin Finck if(!FileDirNdx->FileInfo)
163c2c66affSColin Finck return;
164c2c66affSColin Finck ValidateFileInfo(FileDirNdx->FileInfo);
165c2c66affSColin Finck FileEntry = FileDirNdx->FileInfo->Dloc->FileEntry;
166c2c66affSColin Finck FileDirNdx->FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
167c2c66affSColin Finck }
168c2c66affSColin Finck if(FileEntry->tagIdent == TID_FILE_ENTRY) {
169c2c66affSColin Finck attr = &((PFILE_ENTRY)FileEntry)->permissions;
170c2c66affSColin Finck Flags = &((PFILE_ENTRY)FileEntry)->icbTag.flags;
171c2c66affSColin Finck Type = &((PFILE_ENTRY)FileEntry)->icbTag.fileType;
172c2c66affSColin Finck } else {
173c2c66affSColin Finck attr = &((PEXTENDED_FILE_ENTRY)FileEntry)->permissions;
174c2c66affSColin Finck Flags = &((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.flags;
175c2c66affSColin Finck Type = &((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.fileType;
176c2c66affSColin Finck }
177c2c66affSColin Finck FCharact = &(FileDirNdx->FileCharacteristics);
178c2c66affSColin Finck
179c2c66affSColin Finck if((*FCharact & FILE_DIRECTORY) ||
180c2c66affSColin Finck (*Type == UDF_FILE_TYPE_STREAMDIR) ||
181c2c66affSColin Finck (*Type == UDF_FILE_TYPE_DIRECTORY)) {
182c2c66affSColin Finck *FCharact |= FILE_DIRECTORY;
183c2c66affSColin Finck if(*Type != UDF_FILE_TYPE_STREAMDIR)
184c2c66affSColin Finck *Type = UDF_FILE_TYPE_DIRECTORY;
185c2c66affSColin Finck *attr |= (PERM_O_EXEC | PERM_G_EXEC | PERM_U_EXEC);
186c2c66affSColin Finck NTAttr |= FILE_ATTRIBUTE_DIRECTORY;
187c2c66affSColin Finck NTAttr &= ~FILE_ATTRIBUTE_NORMAL;
188c2c66affSColin Finck } else {
189c2c66affSColin Finck *FCharact &= ~FILE_DIRECTORY;
190c2c66affSColin Finck *Type = UDF_FILE_TYPE_REGULAR;
191c2c66affSColin Finck *attr &= ~(PERM_O_EXEC | PERM_G_EXEC | PERM_U_EXEC);
192c2c66affSColin Finck }
193c2c66affSColin Finck
194c2c66affSColin Finck if(NTAttr & FILE_ATTRIBUTE_SYSTEM) {
195c2c66affSColin Finck *Flags |= ICB_FLAG_SYSTEM;
196c2c66affSColin Finck } else {
197c2c66affSColin Finck *Flags &= ~ICB_FLAG_SYSTEM;
198c2c66affSColin Finck }
199c2c66affSColin Finck if(NTAttr & FILE_ATTRIBUTE_ARCHIVE) {
200c2c66affSColin Finck *Flags |= ICB_FLAG_ARCHIVE;
201c2c66affSColin Finck } else {
202c2c66affSColin Finck *Flags &= ~ICB_FLAG_ARCHIVE;
203c2c66affSColin Finck }
204c2c66affSColin Finck if(NTAttr & FILE_ATTRIBUTE_HIDDEN) {
205c2c66affSColin Finck *FCharact |= FILE_HIDDEN;
206c2c66affSColin Finck } else {
207c2c66affSColin Finck *FCharact &= ~FILE_HIDDEN;
208c2c66affSColin Finck }
209c2c66affSColin Finck *attr |= (PERM_O_READ | PERM_G_READ | PERM_U_READ);
210c2c66affSColin Finck if(!(NTAttr & FILE_ATTRIBUTE_READONLY)) {
211c2c66affSColin Finck *attr |= (PERM_O_WRITE | PERM_G_WRITE | PERM_U_WRITE |
212c2c66affSColin Finck PERM_O_DELETE | PERM_G_DELETE | PERM_U_DELETE |
213c2c66affSColin Finck PERM_O_CHATTR | PERM_G_CHATTR | PERM_U_CHATTR);
214c2c66affSColin Finck } else {
215c2c66affSColin Finck *attr &= ~(PERM_O_WRITE | PERM_G_WRITE | PERM_U_WRITE |
216c2c66affSColin Finck PERM_O_DELETE | PERM_G_DELETE | PERM_U_DELETE |
217c2c66affSColin Finck PERM_O_CHATTR | PERM_G_CHATTR | PERM_U_CHATTR);
218c2c66affSColin Finck }
219c2c66affSColin Finck FileDirNdx->SysAttr = NTAttr;
220c2c66affSColin Finck if(FileDirNdx->FileInfo)
221c2c66affSColin Finck FileDirNdx->FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
222c2c66affSColin Finck FileDirNdx->FI_Flags |= UDF_FI_FLAG_FI_MODIFIED;
223c2c66affSColin Finck return;
224c2c66affSColin Finck } // end UDFAttributesToUDF()
225c2c66affSColin Finck
226c2c66affSColin Finck #ifndef _CONSOLE
227c2c66affSColin Finck /*
228c2c66affSColin Finck This routine fills PFILE_BOTH_DIR_INFORMATION structure (NT)
229c2c66affSColin Finck */
230c2c66affSColin Finck NTSTATUS
UDFFileDirInfoToNT(IN PVCB Vcb,IN PDIR_INDEX_ITEM FileDirNdx,OUT PFILE_BOTH_DIR_INFORMATION NTFileInfo)231c2c66affSColin Finck UDFFileDirInfoToNT(
232c2c66affSColin Finck IN PVCB Vcb,
233c2c66affSColin Finck IN PDIR_INDEX_ITEM FileDirNdx,
234c2c66affSColin Finck OUT PFILE_BOTH_DIR_INFORMATION NTFileInfo
235c2c66affSColin Finck )
236c2c66affSColin Finck {
237c2c66affSColin Finck PFILE_ENTRY FileEntry;
238c2c66affSColin Finck UNICODE_STRING UdfName;
239c2c66affSColin Finck UNICODE_STRING DosName;
240c2c66affSColin Finck PEXTENDED_FILE_ENTRY ExFileEntry;
241c2c66affSColin Finck USHORT Ident;
242*d97e4909SVictor Martinez BOOLEAN ReadSizes = FALSE;
243c2c66affSColin Finck NTSTATUS status;
244c2c66affSColin Finck PtrUDFNTRequiredFCB NtReqFcb;
245c2c66affSColin Finck
246c2c66affSColin Finck UDFPrint(("@=%#x, FileDirNdx %x\n", &Vcb, FileDirNdx));
247c2c66affSColin Finck
248c334c17dSTimo Kreuzer ASSERT((ULONG_PTR)NTFileInfo > 0x1000);
249c2c66affSColin Finck RtlZeroMemory(NTFileInfo, sizeof(FILE_BOTH_DIR_INFORMATION));
250c2c66affSColin Finck
251c2c66affSColin Finck DosName.Buffer = (PWCHAR)&(NTFileInfo->ShortName);
252c2c66affSColin Finck DosName.MaximumLength = sizeof(NTFileInfo->ShortName); // 12*sizeof(WCHAR)
253c2c66affSColin Finck
254c2c66affSColin Finck _SEH2_TRY {
255c2c66affSColin Finck UDFPrint((" DirInfoToNT: %*.*S\n", FileDirNdx->FName.Length/sizeof(WCHAR), FileDirNdx->FName.Length/sizeof(WCHAR), FileDirNdx->FName));
256c2c66affSColin Finck } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
257c2c66affSColin Finck UDFPrint((" DirInfoToNT: exception when printing file name\n"));
258c2c66affSColin Finck } _SEH2_END;
259c2c66affSColin Finck
260c2c66affSColin Finck if(FileDirNdx->FileInfo) {
261c2c66affSColin Finck UDFPrint((" FileInfo\n"));
262c2c66affSColin Finck // validate FileInfo
263c2c66affSColin Finck ValidateFileInfo(FileDirNdx->FileInfo);
264c2c66affSColin Finck if(UDFGetFileLinkCount(FileDirNdx->FileInfo) > 1)
265c2c66affSColin Finck FileDirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
266c2c66affSColin Finck FileEntry = (PFILE_ENTRY)(FileDirNdx->FileInfo->Dloc->FileEntry);
267c2c66affSColin Finck // read required sizes from Fcb (if any) if file is not linked
268c2c66affSColin Finck // otherwise we should read them from FileEntry
269c2c66affSColin Finck if(FileDirNdx->FileInfo->Fcb) {
270c2c66affSColin Finck UDFPrint((" Fcb\n"));
271c2c66affSColin Finck NtReqFcb = FileDirNdx->FileInfo->Fcb->NTRequiredFCB;
272c2c66affSColin Finck NTFileInfo->CreationTime.QuadPart = NtReqFcb->CreationTime.QuadPart;
273c2c66affSColin Finck NTFileInfo->LastWriteTime.QuadPart = NtReqFcb->LastWriteTime.QuadPart;
274c2c66affSColin Finck NTFileInfo->LastAccessTime.QuadPart = NtReqFcb->LastAccessTime.QuadPart;
275c2c66affSColin Finck NTFileInfo->ChangeTime.QuadPart = NtReqFcb->ChangeTime.QuadPart;
276c2c66affSColin Finck // NTFileInfo->AllocationSize.QuadPart = NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart;
277c2c66affSColin Finck NTFileInfo->AllocationSize.QuadPart = FileDirNdx->AllocationSize;
278c2c66affSColin Finck /* FileDirNdx->FileSize =
279c2c66affSColin Finck NTFileInfo->EndOfFile.QuadPart = NtReqFcb->CommonFCBHeader.FileSize.QuadPart;*/
280c2c66affSColin Finck NTFileInfo->EndOfFile.QuadPart = FileDirNdx->FileSize;
281c2c66affSColin Finck if(FileDirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) {
282c2c66affSColin Finck UDFPrint((" SYS_ATTR\n"));
283c2c66affSColin Finck NTFileInfo->FileAttributes = FileDirNdx->SysAttr;
284c2c66affSColin Finck goto get_name_only;
285c2c66affSColin Finck }
286c2c66affSColin Finck FileDirNdx->CreationTime = NTFileInfo->CreationTime.QuadPart;
287c2c66affSColin Finck FileDirNdx->LastWriteTime = NTFileInfo->LastWriteTime.QuadPart;
288c2c66affSColin Finck FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart;
289c2c66affSColin Finck FileDirNdx->ChangeTime = NTFileInfo->ChangeTime.QuadPart;
290c2c66affSColin Finck goto get_attr_only;
291c2c66affSColin Finck }
292c2c66affSColin Finck ASSERT(FileEntry);
293c2c66affSColin Finck } else if(!(FileDirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) ||
294c2c66affSColin Finck (FileDirNdx->FI_Flags & UDF_FI_FLAG_LINKED)) {
295c2c66affSColin Finck LONG_AD feloc;
296c2c66affSColin Finck
297c2c66affSColin Finck UDFPrint((" !SYS_ATTR\n"));
298c2c66affSColin Finck FileEntry = (PFILE_ENTRY)MyAllocatePool__(NonPagedPool, Vcb->LBlockSize);
299c2c66affSColin Finck if(!FileEntry) return STATUS_INSUFFICIENT_RESOURCES;
300c2c66affSColin Finck
301c2c66affSColin Finck feloc.extLength = Vcb->LBlockSize;
302c2c66affSColin Finck feloc.extLocation = FileDirNdx->FileEntryLoc;
303c2c66affSColin Finck
304c2c66affSColin Finck if(!NT_SUCCESS(status = UDFReadFileEntry(Vcb, &feloc, FileEntry, &Ident))) {
305c2c66affSColin Finck UDFPrint((" !UDFReadFileEntry\n"));
306c2c66affSColin Finck MyFreePool__(FileEntry);
307c2c66affSColin Finck FileEntry = NULL;
308c2c66affSColin Finck goto get_name_only;
309c2c66affSColin Finck }
310c2c66affSColin Finck ReadSizes = TRUE;
311c2c66affSColin Finck } else {
312c2c66affSColin Finck UDFPrint((" FileDirNdx\n"));
313c2c66affSColin Finck NTFileInfo->CreationTime.QuadPart = FileDirNdx->CreationTime;
314c2c66affSColin Finck NTFileInfo->LastWriteTime.QuadPart = FileDirNdx->LastWriteTime;
315c2c66affSColin Finck NTFileInfo->LastAccessTime.QuadPart = FileDirNdx->LastAccessTime;
316c2c66affSColin Finck NTFileInfo->ChangeTime.QuadPart = FileDirNdx->ChangeTime;
317c2c66affSColin Finck NTFileInfo->FileAttributes = FileDirNdx->SysAttr;
318c2c66affSColin Finck NTFileInfo->AllocationSize.QuadPart = FileDirNdx->AllocationSize;
319c2c66affSColin Finck NTFileInfo->EndOfFile.QuadPart = FileDirNdx->FileSize;
320c2c66affSColin Finck NTFileInfo->EaSize = 0;
321c2c66affSColin Finck FileEntry = NULL;
322c2c66affSColin Finck goto get_name_only;
323c2c66affSColin Finck }
324c2c66affSColin Finck
325c2c66affSColin Finck if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)
326c2c66affSColin Finck goto get_name_only;
327c2c66affSColin Finck
328c2c66affSColin Finck UDFPrint((" direct\n"));
329c2c66affSColin Finck if(FileEntry->descTag.tagIdent == TID_FILE_ENTRY) {
330c2c66affSColin Finck UDFPrint((" TID_FILE_ENTRY\n"));
331c2c66affSColin Finck if(ReadSizes) {
332c2c66affSColin Finck UDFPrint((" ReadSizes\n"));
333c2c66affSColin Finck // Times
334c2c66affSColin Finck FileDirNdx->CreationTime = NTFileInfo->CreationTime.QuadPart =
335c2c66affSColin Finck FileDirNdx->LastWriteTime = NTFileInfo->LastWriteTime.QuadPart = UDFTimeToNT(&(FileEntry->modificationTime));
336c2c66affSColin Finck FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart = UDFTimeToNT(&(FileEntry->accessTime));
337c2c66affSColin Finck FileDirNdx->ChangeTime = NTFileInfo->ChangeTime.QuadPart = UDFTimeToNT(&(FileEntry->attrTime));
338c2c66affSColin Finck // FileSize
339c2c66affSColin Finck FileDirNdx->FileSize =
340c2c66affSColin Finck NTFileInfo->EndOfFile.QuadPart =
341c2c66affSColin Finck FileEntry->informationLength;
342c2c66affSColin Finck UDFPrint((" informationLength=%I64x, lengthAllocDescs=%I64x\n",
343c2c66affSColin Finck FileEntry->informationLength,
344c2c66affSColin Finck FileEntry->lengthAllocDescs
345c2c66affSColin Finck ));
346c2c66affSColin Finck // AllocSize
347c2c66affSColin Finck FileDirNdx->AllocationSize =
348c2c66affSColin Finck NTFileInfo->AllocationSize.QuadPart =
349c2c66affSColin Finck (FileEntry->informationLength + Vcb->LBlockSize - 1) & ~((LONGLONG)(Vcb->LBlockSize) - 1);
350c2c66affSColin Finck }
351c2c66affSColin Finck // NTFileInfo->EaSize = 0;//FileEntry->lengthExtendedAttr;
352c2c66affSColin Finck } else if(FileEntry->descTag.tagIdent == TID_EXTENDED_FILE_ENTRY) {
353c2c66affSColin Finck ExFileEntry = (PEXTENDED_FILE_ENTRY)FileEntry;
354c2c66affSColin Finck UDFPrint((" PEXTENDED_FILE_ENTRY\n"));
355c2c66affSColin Finck if(ReadSizes) {
356c2c66affSColin Finck UDFPrint((" ReadSizes\n"));
357c2c66affSColin Finck // Times
358c2c66affSColin Finck FileDirNdx->CreationTime = NTFileInfo->CreationTime.QuadPart = UDFTimeToNT(&(ExFileEntry->createTime));
359c2c66affSColin Finck FileDirNdx->LastWriteTime = NTFileInfo->LastWriteTime.QuadPart = UDFTimeToNT(&(ExFileEntry->modificationTime));
360c2c66affSColin Finck FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart = UDFTimeToNT(&(ExFileEntry->accessTime));
361c2c66affSColin Finck FileDirNdx->ChangeTime = NTFileInfo->ChangeTime.QuadPart = UDFTimeToNT(&(ExFileEntry->attrTime));
362c2c66affSColin Finck // FileSize
363c2c66affSColin Finck FileDirNdx->FileSize =
364c2c66affSColin Finck NTFileInfo->EndOfFile.QuadPart =
365c2c66affSColin Finck ExFileEntry->informationLength;
366c2c66affSColin Finck UDFPrint((" informationLength=%I64x, lengthAllocDescs=%I64x\n",
367c2c66affSColin Finck FileEntry->informationLength,
368c2c66affSColin Finck FileEntry->lengthAllocDescs
369c2c66affSColin Finck ));
370c2c66affSColin Finck // AllocSize
371c2c66affSColin Finck FileDirNdx->AllocationSize =
372c2c66affSColin Finck NTFileInfo->AllocationSize.QuadPart =
373c2c66affSColin Finck (ExFileEntry->informationLength + Vcb->LBlockSize - 1) & ~((LONGLONG)(Vcb->LBlockSize) - 1);
374c2c66affSColin Finck }
375c2c66affSColin Finck // NTFileInfo->EaSize = 0;//ExFileEntry->lengthExtendedAttr;
376c2c66affSColin Finck } else {
377c2c66affSColin Finck UDFPrint((" ???\n"));
378c2c66affSColin Finck goto get_name_only;
379c2c66affSColin Finck }
380c2c66affSColin Finck
381c2c66affSColin Finck get_attr_only:
382c2c66affSColin Finck
383c2c66affSColin Finck UDFPrint((" get_attr"));
384c2c66affSColin Finck // do some substitutions
385c2c66affSColin Finck if(!FileDirNdx->CreationTime) {
386c2c66affSColin Finck FileDirNdx->CreationTime = NTFileInfo->CreationTime.QuadPart = Vcb->VolCreationTime;
387c2c66affSColin Finck }
388c2c66affSColin Finck if(!FileDirNdx->LastAccessTime) {
389c2c66affSColin Finck FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart = FileDirNdx->CreationTime;
390c2c66affSColin Finck }
391c2c66affSColin Finck if(!FileDirNdx->LastWriteTime) {
392c2c66affSColin Finck FileDirNdx->LastWriteTime = NTFileInfo->LastWriteTime.QuadPart = FileDirNdx->CreationTime;
393c2c66affSColin Finck }
394c2c66affSColin Finck if(!FileDirNdx->ChangeTime) {
395c2c66affSColin Finck FileDirNdx->ChangeTime = NTFileInfo->ChangeTime.QuadPart = FileDirNdx->CreationTime;
396c2c66affSColin Finck }
397c2c66affSColin Finck
398c2c66affSColin Finck FileDirNdx->SysAttr =
399c2c66affSColin Finck NTFileInfo->FileAttributes = UDFAttributesToNT(FileDirNdx, (tag*)FileEntry);
400c2c66affSColin Finck FileDirNdx->FI_Flags |= UDF_FI_FLAG_SYS_ATTR;
401c2c66affSColin Finck
402c2c66affSColin Finck get_name_only:
403c2c66affSColin Finck // get filename in standard Unicode format
404c2c66affSColin Finck UdfName = FileDirNdx->FName;
405c2c66affSColin Finck NTFileInfo->FileNameLength = UdfName.Length;
406c2c66affSColin Finck RtlCopyMemory((PCHAR)&(NTFileInfo->FileName), (PCHAR)(UdfName.Buffer), UdfName.MaximumLength);
407c2c66affSColin Finck if(!(FileDirNdx->FI_Flags & UDF_FI_FLAG_DOS)) {
408c2c66affSColin Finck UDFPrint((" !UDF_FI_FLAG_DOS"));
409c2c66affSColin Finck UDFDOSName(Vcb, &DosName, &UdfName,
410c2c66affSColin Finck (FileDirNdx->FI_Flags & UDF_FI_FLAG_KEEP_NAME) ? TRUE : FALSE);
411c2c66affSColin Finck NTFileInfo->ShortNameLength = (UCHAR)DosName.Length;
412c2c66affSColin Finck }
413c2c66affSColin Finck // report zero EOF & AllocSize for Dirs
414c2c66affSColin Finck if(FileDirNdx->FileCharacteristics & FILE_DIRECTORY) {
415c2c66affSColin Finck UDFPrint((" FILE_DIRECTORY"));
416c2c66affSColin Finck NTFileInfo->AllocationSize.QuadPart =
417c2c66affSColin Finck NTFileInfo->EndOfFile.QuadPart = 0;
418c2c66affSColin Finck }
419c2c66affSColin Finck UDFPrint((" AllocationSize=%I64x, NTFileInfo->EndOfFile=%I64x", NTFileInfo->AllocationSize.QuadPart, NTFileInfo->EndOfFile.QuadPart));
420c2c66affSColin Finck // free tmp buffer (if any)
421c2c66affSColin Finck UDFPrint(("\n"));
422c2c66affSColin Finck if(FileEntry && !FileDirNdx->FileInfo)
423c2c66affSColin Finck MyFreePool__(FileEntry);
424c2c66affSColin Finck return STATUS_SUCCESS;
425c2c66affSColin Finck } // end UDFFileDirInfoToNT()
426c2c66affSColin Finck
427c2c66affSColin Finck #endif //_CONSOLE
428c2c66affSColin Finck
429c2c66affSColin Finck #ifndef UDF_READ_ONLY_BUILD
430c2c66affSColin Finck /*
431c2c66affSColin Finck This routine changes xxxTime field(s) in (Ext)FileEntry
432c2c66affSColin Finck */
433c2c66affSColin Finck VOID
UDFSetFileXTime(IN PUDF_FILE_INFO FileInfo,IN LONGLONG * CrtTime,IN LONGLONG * AccTime,IN LONGLONG * AttrTime,IN LONGLONG * ChgTime)434c2c66affSColin Finck UDFSetFileXTime(
435c2c66affSColin Finck IN PUDF_FILE_INFO FileInfo,
436c2c66affSColin Finck IN LONGLONG* CrtTime,
437c2c66affSColin Finck IN LONGLONG* AccTime,
438c2c66affSColin Finck IN LONGLONG* AttrTime,
439c2c66affSColin Finck IN LONGLONG* ChgTime
440c2c66affSColin Finck )
441c2c66affSColin Finck {
442c2c66affSColin Finck USHORT Ident;
443c2c66affSColin Finck PDIR_INDEX_ITEM DirNdx;
444c2c66affSColin Finck
445c2c66affSColin Finck ValidateFileInfo(FileInfo);
446c2c66affSColin Finck
447c2c66affSColin Finck FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
448c2c66affSColin Finck DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(FileInfo), FileInfo->Index);
449c2c66affSColin Finck Ident = FileInfo->Dloc->FileEntry->tagIdent;
450c2c66affSColin Finck
451c2c66affSColin Finck if(Ident == TID_FILE_ENTRY) {
452c2c66affSColin Finck PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
453c2c66affSColin Finck
454c2c66affSColin Finck if(AccTime) {
455c2c66affSColin Finck if(DirNdx && *AccTime) DirNdx->LastAccessTime = *AccTime;
456c2c66affSColin Finck UDFTimeToUDF(*AccTime, &(fe->accessTime));
457c2c66affSColin Finck }
458c2c66affSColin Finck if(AttrTime) {
459c2c66affSColin Finck if(DirNdx && *AttrTime) DirNdx->ChangeTime = *AttrTime;
460c2c66affSColin Finck UDFTimeToUDF(*AttrTime, &(fe->attrTime));
461c2c66affSColin Finck }
462c2c66affSColin Finck if(ChgTime) {
463c2c66affSColin Finck if(DirNdx && *ChgTime) DirNdx->CreationTime =
464c2c66affSColin Finck DirNdx->LastWriteTime = *ChgTime;
465c2c66affSColin Finck UDFTimeToUDF(*ChgTime, &(fe->modificationTime));
466c2c66affSColin Finck } else
467c2c66affSColin Finck if(CrtTime) {
468c2c66affSColin Finck if(DirNdx && *CrtTime) DirNdx->CreationTime =
469c2c66affSColin Finck DirNdx->LastWriteTime = *CrtTime;
470c2c66affSColin Finck UDFTimeToUDF(*CrtTime, &(fe->modificationTime));
471c2c66affSColin Finck }
472c2c66affSColin Finck
473c2c66affSColin Finck } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
474c2c66affSColin Finck PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
475c2c66affSColin Finck
476c2c66affSColin Finck if(AccTime) {
477c2c66affSColin Finck if(DirNdx && *AccTime) DirNdx->LastAccessTime = *AccTime;
478c2c66affSColin Finck UDFTimeToUDF(*AccTime, &(fe->accessTime));
479c2c66affSColin Finck }
480c2c66affSColin Finck if(AttrTime) {
481c2c66affSColin Finck if(DirNdx && *AttrTime) DirNdx->ChangeTime = *AttrTime;
482c2c66affSColin Finck UDFTimeToUDF(*AttrTime, &(fe->attrTime));
483c2c66affSColin Finck }
484c2c66affSColin Finck if(ChgTime) {
485c2c66affSColin Finck if(DirNdx && *ChgTime) DirNdx->LastWriteTime = *ChgTime;
486c2c66affSColin Finck UDFTimeToUDF(*ChgTime, &(fe->modificationTime));
487c2c66affSColin Finck }
488c2c66affSColin Finck if(CrtTime) {
489c2c66affSColin Finck if(DirNdx && *CrtTime) DirNdx->CreationTime = *CrtTime;
490c2c66affSColin Finck UDFTimeToUDF(*CrtTime, &(fe->createTime));
491c2c66affSColin Finck }
492c2c66affSColin Finck
493c2c66affSColin Finck }
494c2c66affSColin Finck } // end UDFSetFileXTime()
495c2c66affSColin Finck #endif //UDF_READ_ONLY_BUILD
496c2c66affSColin Finck
497c2c66affSColin Finck /*
498c2c66affSColin Finck This routine gets xxxTime field(s) in (Ext)FileEntry
499c2c66affSColin Finck */
500c2c66affSColin Finck VOID
UDFGetFileXTime(IN PUDF_FILE_INFO FileInfo,OUT LONGLONG * CrtTime,OUT LONGLONG * AccTime,OUT LONGLONG * AttrTime,OUT LONGLONG * ChgTime)501c2c66affSColin Finck UDFGetFileXTime(
502c2c66affSColin Finck IN PUDF_FILE_INFO FileInfo,
503c2c66affSColin Finck OUT LONGLONG* CrtTime,
504c2c66affSColin Finck OUT LONGLONG* AccTime,
505c2c66affSColin Finck OUT LONGLONG* AttrTime,
506c2c66affSColin Finck OUT LONGLONG* ChgTime
507c2c66affSColin Finck )
508c2c66affSColin Finck {
509c2c66affSColin Finck USHORT Ident;
510c2c66affSColin Finck
511c2c66affSColin Finck ValidateFileInfo(FileInfo);
512c2c66affSColin Finck
513c2c66affSColin Finck Ident = FileInfo->Dloc->FileEntry->tagIdent;
514c2c66affSColin Finck
515c2c66affSColin Finck if(Ident == TID_FILE_ENTRY) {
516c2c66affSColin Finck PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
517c2c66affSColin Finck
518c2c66affSColin Finck if(AccTime) *AccTime = UDFTimeToNT(&(fe->accessTime));
519c2c66affSColin Finck if(AttrTime) *AttrTime = UDFTimeToNT(&(fe->attrTime));
520c2c66affSColin Finck if(ChgTime) *ChgTime = UDFTimeToNT(&(fe->modificationTime));
521c2c66affSColin Finck if(CrtTime) {
522c2c66affSColin Finck (*CrtTime) = *ChgTime;
523c2c66affSColin Finck }
524c2c66affSColin Finck
525c2c66affSColin Finck } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
526c2c66affSColin Finck PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
527c2c66affSColin Finck
528c2c66affSColin Finck if(AccTime) *AccTime = UDFTimeToNT(&(fe->accessTime));
529c2c66affSColin Finck if(AttrTime) *AttrTime = UDFTimeToNT(&(fe->attrTime));
530c2c66affSColin Finck if(ChgTime) *ChgTime = UDFTimeToNT(&(fe->modificationTime));
531c2c66affSColin Finck if(CrtTime) *CrtTime = UDFTimeToNT(&(fe->createTime));
532c2c66affSColin Finck
533c2c66affSColin Finck }
534c2c66affSColin Finck if(CrtTime) {
535c2c66affSColin Finck if(!(*CrtTime))
536c2c66affSColin Finck KeQuerySystemTime((PLARGE_INTEGER)CrtTime);
537c2c66affSColin Finck if(AccTime && !(*AccTime)) (*AccTime) = *CrtTime;
538c2c66affSColin Finck if(AttrTime && !(*AttrTime)) (*AttrTime) = *CrtTime;
539c2c66affSColin Finck if(AccTime && !(*AccTime)) (*AccTime) = *CrtTime;
540c2c66affSColin Finck }
541c2c66affSColin Finck } // end UDFGetFileXTime()
542c2c66affSColin Finck
543c2c66affSColin Finck VOID
UDFNormalizeFileName(IN PUNICODE_STRING FName,IN USHORT valueCRC)544c2c66affSColin Finck UDFNormalizeFileName(
545c2c66affSColin Finck IN PUNICODE_STRING FName,
546c2c66affSColin Finck IN USHORT valueCRC
547c2c66affSColin Finck )
548c2c66affSColin Finck {
549c2c66affSColin Finck PWCHAR buffer;
550c2c66affSColin Finck USHORT len;
551c2c66affSColin Finck
552c2c66affSColin Finck len = FName->Length/sizeof(WCHAR);
553c2c66affSColin Finck buffer = FName->Buffer;
554c2c66affSColin Finck
555c2c66affSColin Finck // check for '', '.' & '..'
556c2c66affSColin Finck if(!len) return;
557c2c66affSColin Finck if(!buffer[len-1]) {
558c2c66affSColin Finck FName->Length-=sizeof(WCHAR);
559c2c66affSColin Finck len--;
560c2c66affSColin Finck }
561c2c66affSColin Finck if(!len) return;
562c2c66affSColin Finck if(buffer[0] == UNICODE_PERIOD) {
563c2c66affSColin Finck if(len == 1) return;
564c2c66affSColin Finck if((buffer[1] == UNICODE_PERIOD) && (len == 2)) return;
565c2c66affSColin Finck }
566c2c66affSColin Finck
567c2c66affSColin Finck // check for trailing '.'
568c2c66affSColin Finck for(len--;len;len--) {
569c2c66affSColin Finck if( ((buffer[len] == UNICODE_PERIOD) || (buffer[len] == UNICODE_SPACE)) ) {
570c2c66affSColin Finck FName->Length-=sizeof(WCHAR);
571c2c66affSColin Finck buffer[len] = 0;
572c2c66affSColin Finck } else
573c2c66affSColin Finck break;
574c2c66affSColin Finck }
575c2c66affSColin Finck } // end UDFNormalizeFileName()
576c2c66affSColin Finck
577c2c66affSColin Finck #ifndef _CONSOLE
578c2c66affSColin Finck
579c2c66affSColin Finck void
580c2c66affSColin Finck __fastcall
UDFDOSNameOsNative(IN OUT PUNICODE_STRING DosName,IN PUNICODE_STRING UdfName,IN BOOLEAN KeepIntact)581c2c66affSColin Finck UDFDOSNameOsNative(
582c2c66affSColin Finck IN OUT PUNICODE_STRING DosName,
583c2c66affSColin Finck IN PUNICODE_STRING UdfName,
584c2c66affSColin Finck IN BOOLEAN KeepIntact
585c2c66affSColin Finck )
586c2c66affSColin Finck {
587c2c66affSColin Finck PWCHAR dosName = DosName->Buffer;
588c2c66affSColin Finck PWCHAR udfName = UdfName->Buffer;
589c2c66affSColin Finck uint32 udfLen = UdfName->Length / sizeof(WCHAR);
590c2c66affSColin Finck GENERATE_NAME_CONTEXT Ctx;
591c2c66affSColin Finck
592c2c66affSColin Finck if(KeepIntact &&
593c2c66affSColin Finck (udfLen <= 2) && (udfName[0] == UNICODE_PERIOD)) {
594c2c66affSColin Finck if((udfLen != 2) || (udfName[1] == UNICODE_PERIOD)) {
595c2c66affSColin Finck RtlCopyMemory(dosName, udfName, UdfName->Length);
596c2c66affSColin Finck DosName->Length = UdfName->Length;
597c2c66affSColin Finck return;
598c2c66affSColin Finck }
599c2c66affSColin Finck }
600c2c66affSColin Finck RtlZeroMemory(&Ctx, sizeof(GENERATE_NAME_CONTEXT));
601c2c66affSColin Finck RtlGenerate8dot3Name(UdfName, FALSE, &Ctx, DosName);
602c2c66affSColin Finck
603c2c66affSColin Finck } // UDFDOSNameOsNative()
604c2c66affSColin Finck
605c2c66affSColin Finck #endif //_CONSOLE
606c2c66affSColin Finck
607c2c66affSColin Finck /*VOID
608c2c66affSColin Finck UDFNormalizeFileName(
609c2c66affSColin Finck IN PUNICODE_STRING FName,
610c2c66affSColin Finck IN USHORT valueCRC
611c2c66affSColin Finck )
612c2c66affSColin Finck {
613c2c66affSColin Finck WCHAR _newName[UDF_NAME_LEN+5];
614c2c66affSColin Finck PWCHAR newName = (PWCHAR)(&_newName);
615c2c66affSColin Finck PWCHAR udfName = FName->Buffer;
616c2c66affSColin Finck LONG udfLen = FName->Length >> 1;
617c2c66affSColin Finck
618c2c66affSColin Finck LONG index, newIndex = 0, extIndex = 0, newExtIndex = 0, trailIndex = 0;
619c2c66affSColin Finck BOOLEAN needsCRC = FALSE, hasExt = FALSE;
620c2c66affSColin Finck WCHAR ext[UDF_EXT_SIZE], current;
621c2c66affSColin Finck
622c2c66affSColin Finck // handle CurrentDir ('.') and ParentDir ('..') cases
623c2c66affSColin Finck if((udfLen <= 2) && (udfName[0] == UNICODE_PERIOD)) {
624c2c66affSColin Finck if((udfLen != 2) || (udfName[1] == UNICODE_PERIOD))
625c2c66affSColin Finck return;
626c2c66affSColin Finck }
627c2c66affSColin Finck
628c2c66affSColin Finck for (index = 0 ; index < udfLen ; index++) {
629c2c66affSColin Finck current = udfName[index];
630c2c66affSColin Finck
631c2c66affSColin Finck // Look for illegal or unprintable characters.
632c2c66affSColin Finck if (UDFIsIllegalChar(current) || !UnicodeIsPrint(current)) {
633c2c66affSColin Finck needsCRC = TRUE;
634c2c66affSColin Finck current = ILLEGAL_CHAR_MARK;
635c2c66affSColin Finck // Skip Illegal characters(even spaces),
636c2c66affSColin Finck // but not periods.
637c2c66affSColin Finck while(index+1 < udfLen &&
638c2c66affSColin Finck (UDFIsIllegalChar(udfName[index+1]) ||
639c2c66affSColin Finck !UnicodeIsPrint(udfName[index+1])) &&
640c2c66affSColin Finck udfName[index+1] != UNICODE_PERIOD)
641c2c66affSColin Finck index++;
642c2c66affSColin Finck }
643c2c66affSColin Finck
644c2c66affSColin Finck // Record position of extension, if one is found.
645c2c66affSColin Finck if ((current == UNICODE_PERIOD) && ((udfLen - index -1) <= UDF_EXT_SIZE)) {
646c2c66affSColin Finck if (udfLen == index + 1) {
647c2c66affSColin Finck // A trailing period is NOT an extension.
648c2c66affSColin Finck hasExt = FALSE;
649c2c66affSColin Finck } else {
650c2c66affSColin Finck hasExt = TRUE;
651c2c66affSColin Finck extIndex = index;
652c2c66affSColin Finck newExtIndex = newIndex;
653c2c66affSColin Finck }
654c2c66affSColin Finck } else if((current != UNICODE_PERIOD) && (current != UNICODE_SPACE)) {
655c2c66affSColin Finck trailIndex = index;
656c2c66affSColin Finck }
657c2c66affSColin Finck
658c2c66affSColin Finck // if (newIndex < MAXLEN) // tshi is always TRUE for WINNT
659c2c66affSColin Finck newName[newIndex] = current;
660c2c66affSColin Finck newIndex++;
661c2c66affSColin Finck
662c2c66affSColin Finck // For OS2, 95 & NT, truncate any trailing periods and\or spaces.
663c2c66affSColin Finck if (trailIndex != (newIndex - 1)) {
664c2c66affSColin Finck newIndex = trailIndex + 1;
665c2c66affSColin Finck needsCRC = TRUE;
666c2c66affSColin Finck hasExt = FALSE; // Trailing period does not make an extension.
667c2c66affSColin Finck }
668c2c66affSColin Finck }
669c2c66affSColin Finck
670c2c66affSColin Finck if (needsCRC) {
671c2c66affSColin Finck int localExtIndex = 0;
672c2c66affSColin Finck if (hasExt) {
673c2c66affSColin Finck int maxFilenameLen;
674c2c66affSColin Finck // Translate extension, and store it in ext.
675c2c66affSColin Finck for(index = 0; index<UDF_EXT_SIZE && extIndex + index +1 < udfLen; index++ ) {
676c2c66affSColin Finck current = udfName[extIndex + index + 1];
677c2c66affSColin Finck if (UDFIsIllegalChar(current) //|| !UnicodeIsPrint(current)) {
678c2c66affSColin Finck needsCRC = TRUE;
679c2c66affSColin Finck // Replace Illegal and non-displayable chars
680c2c66affSColin Finck // with underscore.
681c2c66affSColin Finck current = ILLEGAL_CHAR_MARK;
682c2c66affSColin Finck // Skip any other illegal or non-displayable
683c2c66affSColin Finck // characters.
684c2c66affSColin Finck while(index + 1 < UDF_EXT_SIZE &&
685c2c66affSColin Finck (UDFIsIllegalChar(udfName[extIndex + index + 2]) ||
686c2c66affSColin Finck !UnicodeIsPrint(udfName[extIndex + index + 2])) )
687c2c66affSColin Finck index++;
688c2c66affSColin Finck }
689c2c66affSColin Finck ext[localExtIndex++] = current;
690c2c66affSColin Finck }
691c2c66affSColin Finck // Truncate filename to leave room for extension and CRC.
692c2c66affSColin Finck maxFilenameLen = ((UDF_NAME_LEN - 4) - localExtIndex - 1);
693c2c66affSColin Finck if (newIndex > maxFilenameLen) {
694c2c66affSColin Finck newIndex = maxFilenameLen;
695c2c66affSColin Finck } else {
696c2c66affSColin Finck newIndex = newExtIndex;
697c2c66affSColin Finck }
698c2c66affSColin Finck } else if (newIndex > UDF_NAME_LEN - 5) {
699c2c66affSColin Finck //If no extension, make sure to leave room for CRC.
700c2c66affSColin Finck newIndex = UDF_NAME_LEN - 5;
701c2c66affSColin Finck }
702c2c66affSColin Finck newName[newIndex++] = UNICODE_CRC_MARK; // Add mark for CRC.
703c2c66affSColin Finck //Calculate CRC from original filename from FileIdentifier.
704c2c66affSColin Finck // valueCRC = UDFUnicodeCksum(fidName, fidNameLen);
705c2c66affSColin Finck // / Convert 16-bits of CRC to hex characters.
706c2c66affSColin Finck newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
707c2c66affSColin Finck newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
708c2c66affSColin Finck newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
709c2c66affSColin Finck newName[newIndex++] = hexChar[(valueCRC & 0x000f)];
710c2c66affSColin Finck // Place a translated extension at end, if found.
711c2c66affSColin Finck if (hasExt) {
712c2c66affSColin Finck newName[newIndex++] = UNICODE_PERIOD;
713c2c66affSColin Finck for (index = 0;index < localExtIndex ;index++ ) {
714c2c66affSColin Finck newName[newIndex++] = ext[index];
715c2c66affSColin Finck }
716c2c66affSColin Finck }
717c2c66affSColin Finck }
718c2c66affSColin Finck
719c2c66affSColin Finck if(FName->Length == (USHORT)newIndex*sizeof(WCHAR)) {
720c2c66affSColin Finck RtlCopyMemory(FName->Buffer, newName, newIndex*sizeof(WCHAR));
721c2c66affSColin Finck return;
722c2c66affSColin Finck }
723c2c66affSColin Finck MyFreePool__(FName->Buffer);
724c2c66affSColin Finck FName->Buffer = (PWCHAR)MyAllocatePool__(UDF_FILENAME_MT, (newIndex+1)*sizeof(WCHAR));
725c2c66affSColin Finck if(FName->Buffer) {
726c2c66affSColin Finck FName->Buffer[newIndex] = 0;
727c2c66affSColin Finck RtlCopyMemory(FName->Buffer, newName, newIndex*sizeof(WCHAR));
728c2c66affSColin Finck }
729c2c66affSColin Finck FName->Length = (USHORT)newIndex*sizeof(WCHAR);
730c2c66affSColin Finck FName->MaximumLength = (USHORT)(newIndex+1)*sizeof(WCHAR);
731c2c66affSColin Finck }*/
732c2c66affSColin Finck
733c2c66affSColin Finck /*PUDF_FILE_INFO
734c2c66affSColin Finck UDFAllocFileInfo(
735c2c66affSColin Finck return ExAllocateFromZone(&(UDFGlobalData.FileInfoZoneHeader));
736c2c66affSColin Finck )*/
737c2c66affSColin Finck
738c2c66affSColin Finck #define STRING_BUFFER_ALIGNMENT (32)
739c2c66affSColin Finck #define STRING_BUFFER_ALIGN(sz) (((sz)+STRING_BUFFER_ALIGNMENT)&(~((ULONG)(STRING_BUFFER_ALIGNMENT-1))))
740c2c66affSColin Finck
741c2c66affSColin Finck NTSTATUS
MyAppendUnicodeStringToString_(IN PUNICODE_STRING Str1,IN PUNICODE_STRING Str2,IN PCHAR Tag)742c2c66affSColin Finck MyAppendUnicodeStringToString_(
743c2c66affSColin Finck IN PUNICODE_STRING Str1,
744c2c66affSColin Finck IN PUNICODE_STRING Str2
745c2c66affSColin Finck #ifdef UDF_TRACK_UNICODE_STR
746c2c66affSColin Finck ,IN PCHAR Tag
747c2c66affSColin Finck #endif
748c2c66affSColin Finck )
749c2c66affSColin Finck {
750c2c66affSColin Finck PWCHAR tmp;
751c2c66affSColin Finck USHORT i;
752c2c66affSColin Finck
753c2c66affSColin Finck #ifdef UDF_TRACK_UNICODE_STR
754c2c66affSColin Finck #define UDF_UNC_STR_TAG Tag
755c2c66affSColin Finck #else
756c2c66affSColin Finck #define UDF_UNC_STR_TAG "AppUStr"
757c2c66affSColin Finck #endif
758c2c66affSColin Finck
759c2c66affSColin Finck tmp = Str1->Buffer;
760c2c66affSColin Finck i = Str1->Length + Str2->Length + sizeof(WCHAR);
761c2c66affSColin Finck ASSERT(Str1->MaximumLength);
762c2c66affSColin Finck if(i > Str1->MaximumLength) {
763c2c66affSColin Finck if(!MyReallocPool__((PCHAR)tmp, Str1->MaximumLength,
764c2c66affSColin Finck (PCHAR*)&tmp, STRING_BUFFER_ALIGN(i)*2) ) {
765c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
766c2c66affSColin Finck }
767c2c66affSColin Finck Str1->MaximumLength = i*2;
768c2c66affSColin Finck Str1->Buffer = tmp;
769c2c66affSColin Finck }
770c2c66affSColin Finck RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2->Buffer, Str2->Length);
771c2c66affSColin Finck
772c2c66affSColin Finck /* tmp = (PWCHAR)MyAllocatePoolTag__(NonPagedPool, i = Str1->Length + Str2->Length + sizeof(WCHAR), UDF_UNC_STR_TAG);
773c2c66affSColin Finck if(!tmp)
774c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
775c2c66affSColin Finck RtlCopyMemory(tmp, Str1->Buffer, Str1->Length);
776c2c66affSColin Finck RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2->Buffer, Str2->Length);*/
777c2c66affSColin Finck tmp[(i / sizeof(WCHAR)) - 1] = 0;
778c2c66affSColin Finck Str1->Length = i - sizeof(WCHAR);
779c2c66affSColin Finck //MyFreePool__(Str1->Buffer);
780c2c66affSColin Finck #ifdef UDF_DBG
781c2c66affSColin Finck if(Str1->Buffer && (Str1->Length >= 2*sizeof(WCHAR))) {
782c2c66affSColin Finck ASSERT((Str1->Buffer[0] != L'\\') || (Str1->Buffer[1] != L'\\'));
783c2c66affSColin Finck }
784c2c66affSColin Finck #endif // UDF_DBG
785c2c66affSColin Finck return STATUS_SUCCESS;
786c2c66affSColin Finck
787c2c66affSColin Finck #undef UDF_UNC_STR_TAG
788c2c66affSColin Finck
789c2c66affSColin Finck } // end MyAppendUnicodeStringToString()
790c2c66affSColin Finck
791c2c66affSColin Finck NTSTATUS
MyAppendUnicodeToString_(IN PUNICODE_STRING Str1,IN PCWSTR Str2,IN PCHAR Tag)792c2c66affSColin Finck MyAppendUnicodeToString_(
793c2c66affSColin Finck IN PUNICODE_STRING Str1,
794c2c66affSColin Finck IN PCWSTR Str2
795c2c66affSColin Finck #ifdef UDF_TRACK_UNICODE_STR
796c2c66affSColin Finck ,IN PCHAR Tag
797c2c66affSColin Finck #endif
798c2c66affSColin Finck )
799c2c66affSColin Finck {
800c2c66affSColin Finck PWCHAR tmp;
801c2c66affSColin Finck USHORT i;
802c2c66affSColin Finck
803c2c66affSColin Finck #ifdef UDF_TRACK_UNICODE_STR
804c2c66affSColin Finck #define UDF_UNC_STR_TAG Tag
805c2c66affSColin Finck #else
806c2c66affSColin Finck #define UDF_UNC_STR_TAG "AppStr"
807c2c66affSColin Finck #endif
808c2c66affSColin Finck
8095bf1fbecSAmine Khaldi #if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
810c2c66affSColin Finck
811c2c66affSColin Finck __asm push ebx
812c2c66affSColin Finck __asm push esi
813c2c66affSColin Finck
814c2c66affSColin Finck __asm xor ebx,ebx
815c2c66affSColin Finck __asm mov esi,Str2
816c2c66affSColin Finck Scan_1:
817c2c66affSColin Finck __asm cmp [word ptr esi+ebx],0
818c2c66affSColin Finck __asm je EO_Scan
819c2c66affSColin Finck __asm add ebx,2
820c2c66affSColin Finck __asm jmp Scan_1
821c2c66affSColin Finck EO_Scan:
822c2c66affSColin Finck __asm mov i,bx
823c2c66affSColin Finck
824c2c66affSColin Finck __asm pop esi
825c2c66affSColin Finck __asm pop ebx
826c2c66affSColin Finck
827c2c66affSColin Finck #else // NO X86 optimization, use generic C/C++
828c2c66affSColin Finck
829c2c66affSColin Finck i=0;
830c2c66affSColin Finck while(Str2[i]) {
831c2c66affSColin Finck i++;
832c2c66affSColin Finck }
833c2c66affSColin Finck i *= sizeof(WCHAR);
834c2c66affSColin Finck
835c2c66affSColin Finck #endif // _X86_
836c2c66affSColin Finck
837c2c66affSColin Finck tmp = Str1->Buffer;
838c2c66affSColin Finck ASSERT(Str1->MaximumLength);
839c2c66affSColin Finck if((Str1->Length+i+sizeof(WCHAR)) > Str1->MaximumLength) {
840c2c66affSColin Finck if(!MyReallocPool__((PCHAR)tmp, Str1->MaximumLength,
841c2c66affSColin Finck (PCHAR*)&tmp, STRING_BUFFER_ALIGN(i + Str1->Length + sizeof(WCHAR))*2 ) ) {
842c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
843c2c66affSColin Finck }
844c2c66affSColin Finck Str1->MaximumLength = STRING_BUFFER_ALIGN(i + sizeof(WCHAR))*2;
845c2c66affSColin Finck Str1->Buffer = tmp;
846c2c66affSColin Finck }
847c2c66affSColin Finck RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2, i);
848c2c66affSColin Finck i+=Str1->Length;
849c2c66affSColin Finck tmp[(i / sizeof(WCHAR))] = 0;
850c2c66affSColin Finck Str1->Length = i;
851c2c66affSColin Finck #ifdef UDF_DBG
852c2c66affSColin Finck /* if(Str1->Buffer && (Str1->Length >= 2*sizeof(WCHAR))) {
853c2c66affSColin Finck ASSERT((Str1->Buffer[0] != L'\\') || (Str1->Buffer[1] != L'\\'));
854c2c66affSColin Finck }*/
855c2c66affSColin Finck #endif // UDF_DBG
856c2c66affSColin Finck return STATUS_SUCCESS;
857c2c66affSColin Finck
858c2c66affSColin Finck #undef UDF_UNC_STR_TAG
859c2c66affSColin Finck
860c2c66affSColin Finck } // end MyAppendUnicodeToString_()
861c2c66affSColin Finck
862c2c66affSColin Finck NTSTATUS
MyInitUnicodeString(IN PUNICODE_STRING Str1,IN PCWSTR Str2)863c2c66affSColin Finck MyInitUnicodeString(
864c2c66affSColin Finck IN PUNICODE_STRING Str1,
865c2c66affSColin Finck IN PCWSTR Str2
866c2c66affSColin Finck )
867c2c66affSColin Finck {
868c2c66affSColin Finck
869c2c66affSColin Finck USHORT i;
870c2c66affSColin Finck
8715bf1fbecSAmine Khaldi #if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
872c2c66affSColin Finck
873c2c66affSColin Finck __asm push ebx
874c2c66affSColin Finck __asm push esi
875c2c66affSColin Finck
876c2c66affSColin Finck __asm xor ebx,ebx
877c2c66affSColin Finck __asm mov esi,Str2
878c2c66affSColin Finck Scan_1:
879c2c66affSColin Finck __asm cmp [word ptr esi+ebx],0
880c2c66affSColin Finck __asm je EO_Scan
881c2c66affSColin Finck __asm add ebx,2
882c2c66affSColin Finck __asm jmp Scan_1
883c2c66affSColin Finck EO_Scan:
884c2c66affSColin Finck __asm mov i,bx
885c2c66affSColin Finck
886c2c66affSColin Finck __asm pop esi
887c2c66affSColin Finck __asm pop ebx
888c2c66affSColin Finck
889c2c66affSColin Finck #else // NO X86 optimization, use generic C/C++
890c2c66affSColin Finck
891c2c66affSColin Finck i=0;
892c2c66affSColin Finck while(Str2[i]) {
893c2c66affSColin Finck i++;
894c2c66affSColin Finck }
895c2c66affSColin Finck i *= sizeof(WCHAR);
896c2c66affSColin Finck
897c2c66affSColin Finck #endif // _X86_
898c2c66affSColin Finck
899c2c66affSColin Finck Str1->MaximumLength = STRING_BUFFER_ALIGN((Str1->Length = i) + sizeof(WCHAR));
900c2c66affSColin Finck Str1->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, Str1->MaximumLength);
901c2c66affSColin Finck if(!Str1->Buffer)
902c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
903c2c66affSColin Finck RtlCopyMemory(Str1->Buffer, Str2, i);
904c2c66affSColin Finck Str1->Buffer[i/sizeof(WCHAR)] = 0;
905c2c66affSColin Finck return STATUS_SUCCESS;
906c2c66affSColin Finck
907c2c66affSColin Finck } // end MyInitUnicodeString()
908c2c66affSColin Finck
909c2c66affSColin Finck NTSTATUS
MyCloneUnicodeString(IN PUNICODE_STRING Str1,IN PUNICODE_STRING Str2)910c2c66affSColin Finck MyCloneUnicodeString(
911c2c66affSColin Finck IN PUNICODE_STRING Str1,
912c2c66affSColin Finck IN PUNICODE_STRING Str2
913c2c66affSColin Finck )
914c2c66affSColin Finck {
915c2c66affSColin Finck Str1->MaximumLength = STRING_BUFFER_ALIGN((Str1->Length = Str2->Length) + sizeof(WCHAR));
916c2c66affSColin Finck Str1->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, Str1->MaximumLength);
917c2c66affSColin Finck if(!Str1->Buffer)
918c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
919c2c66affSColin Finck ASSERT(Str2->Buffer);
920c2c66affSColin Finck RtlCopyMemory(Str1->Buffer, Str2->Buffer, Str2->Length);
921c2c66affSColin Finck Str1->Buffer[Str1->Length/sizeof(WCHAR)] = 0;
922c2c66affSColin Finck return STATUS_SUCCESS;
923c2c66affSColin Finck
924c2c66affSColin Finck } // end MyCloneUnicodeString()
925c2c66affSColin Finck
926c2c66affSColin Finck /*
927c2c66affSColin Finck This routine checks do we needn't read something from disk to
928c2c66affSColin Finck obtain Attributes & so on
929c2c66affSColin Finck */
930c2c66affSColin Finck BOOLEAN
UDFIsDirInfoCached(IN PVCB Vcb,IN PUDF_FILE_INFO DirInfo)931c2c66affSColin Finck UDFIsDirInfoCached(
932c2c66affSColin Finck IN PVCB Vcb,
933c2c66affSColin Finck IN PUDF_FILE_INFO DirInfo
934c2c66affSColin Finck )
935c2c66affSColin Finck {
936c2c66affSColin Finck PDIR_INDEX_HDR hDirNdx = DirInfo->Dloc->DirIndex;
937c2c66affSColin Finck PDIR_INDEX_ITEM DirNdx;
938c2c66affSColin Finck for(uint_di i=2; (DirNdx = UDFDirIndex(hDirNdx,i)); i++) {
939c2c66affSColin Finck if(!(DirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) ||
940c2c66affSColin Finck (DirNdx->FI_Flags & UDF_FI_FLAG_LINKED)) return FALSE;
941c2c66affSColin Finck }
942c2c66affSColin Finck return TRUE;
943c2c66affSColin Finck } // end UDFIsDirInfoCached()
944c2c66affSColin Finck
945c2c66affSColin Finck #ifndef UDF_READ_ONLY_BUILD
946c2c66affSColin Finck NTSTATUS
UDFDoesOSAllowFileToBeTargetForRename__(IN PUDF_FILE_INFO FileInfo)947c2c66affSColin Finck UDFDoesOSAllowFileToBeTargetForRename__(
948c2c66affSColin Finck IN PUDF_FILE_INFO FileInfo
949c2c66affSColin Finck )
950c2c66affSColin Finck {
951c2c66affSColin Finck #ifndef _CONSOLE
952c2c66affSColin Finck NTSTATUS RC;
953c2c66affSColin Finck #endif //_CONSOLE
954c2c66affSColin Finck
955c2c66affSColin Finck if(UDFIsADirectory(FileInfo))
956c2c66affSColin Finck return STATUS_ACCESS_DENIED;
957c2c66affSColin Finck if(!FileInfo->ParentFile)
958c2c66affSColin Finck return STATUS_ACCESS_DENIED;
959c2c66affSColin Finck
960c2c66affSColin Finck if(UDFAttributesToNT(UDFDirIndex(UDFGetDirIndexByFileInfo(FileInfo),FileInfo->Index),
961c2c66affSColin Finck FileInfo->Dloc->FileEntry) & FILE_ATTRIBUTE_READONLY)
962c2c66affSColin Finck return STATUS_ACCESS_DENIED;
963c2c66affSColin Finck
964c2c66affSColin Finck if(!FileInfo->Fcb)
965c2c66affSColin Finck return STATUS_SUCCESS;
966c2c66affSColin Finck #ifndef _CONSOLE
967c2c66affSColin Finck RC = UDFCheckAccessRights(NULL, NULL, FileInfo->Fcb, NULL, DELETE, 0);
968c2c66affSColin Finck if(!NT_SUCCESS(RC))
969c2c66affSColin Finck return RC;
970c2c66affSColin Finck #endif //_CONSOLE
971c2c66affSColin Finck if(!FileInfo->Fcb)
972c2c66affSColin Finck return STATUS_SUCCESS;
973c2c66affSColin Finck // RC = UDFMarkStreamsForDeletion(FileInfo->Fcb->Vcb, FileInfo->Fcb, TRUE); // Delete
974c2c66affSColin Finck /* RC = UDFSetDispositionInformation(FileInfo->Fcb, NULL,
975c2c66affSColin Finck FileInfo->Fcb->Vcb, NULL, TRUE);
976c2c66affSColin Finck if(NT_SUCCESS(RC)) {
977c2c66affSColin Finck FileInfo->Fcb->FCBFlags |= UDF_FCB_DELETED;
978c2c66affSColin Finck if(UDFGetFileLinkCount(FileInfo) <= 1) {
979c2c66affSColin Finck FileInfo->Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_DELETED;
980c2c66affSColin Finck }
981c2c66affSColin Finck }
982c2c66affSColin Finck return RC;*/
983c2c66affSColin Finck return STATUS_ACCESS_DENIED;
984c2c66affSColin Finck
985c2c66affSColin Finck } // end UDFDoesOSAllowFileToBeTargetForRename__()
986c2c66affSColin Finck
987c2c66affSColin Finck NTSTATUS
UDFDoesOSAllowFileToBeUnlinked__(IN PUDF_FILE_INFO FileInfo)988c2c66affSColin Finck UDFDoesOSAllowFileToBeUnlinked__(
989c2c66affSColin Finck IN PUDF_FILE_INFO FileInfo
990c2c66affSColin Finck )
991c2c66affSColin Finck {
992c2c66affSColin Finck PDIR_INDEX_HDR hCurDirNdx;
993c2c66affSColin Finck PDIR_INDEX_ITEM CurDirNdx;
994c2c66affSColin Finck uint_di i;
995c2c66affSColin Finck // IO_STATUS_BLOCK IoStatus;
996c2c66affSColin Finck
997c2c66affSColin Finck ASSERT(FileInfo->Dloc);
998c2c66affSColin Finck
999c2c66affSColin Finck if(!FileInfo->ParentFile)
1000c2c66affSColin Finck return STATUS_CANNOT_DELETE;
1001c2c66affSColin Finck if(FileInfo->Dloc->SDirInfo)
1002c2c66affSColin Finck return STATUS_CANNOT_DELETE;
1003c2c66affSColin Finck if(!UDFIsADirectory(FileInfo))
1004c2c66affSColin Finck return STATUS_SUCCESS;
1005c2c66affSColin Finck
1006c2c66affSColin Finck // UDFFlushAFile(FileInfo->Fcb, NULL, &IoStatus, 0);
1007c2c66affSColin Finck hCurDirNdx = FileInfo->Dloc->DirIndex;
1008c2c66affSColin Finck // check if we can delete all files
1009c2c66affSColin Finck for(i=2; (CurDirNdx = UDFDirIndex(hCurDirNdx,i)); i++) {
1010c2c66affSColin Finck // try to open Stream
1011c2c66affSColin Finck if(CurDirNdx->FileInfo)
1012c2c66affSColin Finck return STATUS_CANNOT_DELETE;
1013c2c66affSColin Finck }
1014c2c66affSColin Finck // return UDFCheckAccessRights(NULL, NULL, FileInfo->Fcb, NULL, DELETE, 0);
1015c2c66affSColin Finck return STATUS_SUCCESS;
1016c2c66affSColin Finck } // end UDFDoesOSAllowFileToBeUnlinked__()
1017c2c66affSColin Finck
1018c2c66affSColin Finck NTSTATUS
UDFDoesOSAllowFilePretendDeleted__(IN PUDF_FILE_INFO FileInfo)1019c2c66affSColin Finck UDFDoesOSAllowFilePretendDeleted__(
1020c2c66affSColin Finck IN PUDF_FILE_INFO FileInfo
1021c2c66affSColin Finck )
1022c2c66affSColin Finck {
1023c2c66affSColin Finck PDIR_INDEX_HDR hDirNdx = UDFGetDirIndexByFileInfo(FileInfo);
1024c2c66affSColin Finck if(!hDirNdx) return STATUS_CANNOT_DELETE;
1025c2c66affSColin Finck PDIR_INDEX_ITEM DirNdx = UDFDirIndex(hDirNdx, FileInfo->Index);
1026c2c66affSColin Finck if(!DirNdx) return STATUS_CANNOT_DELETE;
1027c2c66affSColin Finck // we can't hide file that is not marked as deleted
1028c2c66affSColin Finck if(!(DirNdx->FileCharacteristics & FILE_DELETED)) {
1029c2c66affSColin Finck BrutePoint();
1030c2c66affSColin Finck
1031c2c66affSColin Finck #ifndef _CONSOLE
1032c2c66affSColin Finck if(!(FileInfo->Fcb->FCBFlags & (UDF_FCB_DELETE_ON_CLOSE |
1033c2c66affSColin Finck UDF_FCB_DELETED) ))
1034c2c66affSColin Finck #endif //_CONSOLE
1035c2c66affSColin Finck
1036c2c66affSColin Finck return STATUS_CANNOT_DELETE;
1037c2c66affSColin Finck }
1038c2c66affSColin Finck return STATUS_SUCCESS;
1039c2c66affSColin Finck }
1040c2c66affSColin Finck #endif //UDF_READ_ONLY_BUILD
1041c2c66affSColin Finck
1042