update for HEAD-2003091401
[reactos.git] / drivers / fs / ntfs / attrib.c
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2002,2003 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /* $Id$
20  *
21  * COPYRIGHT:        See COPYING in the top level directory
22  * PROJECT:          ReactOS kernel
23  * FILE:             drivers/fs/ntfs/attrib.c
24  * PURPOSE:          NTFS filesystem driver
25  * PROGRAMMER:       Eric Kohl
26  */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31
32 #include <ntos.h>
33
34 //#define NDEBUG
35 #include <debug.h>
36
37 #include "ntfs.h"
38
39
40 /* FUNCTIONS ****************************************************************/
41
42 VOID
43 NtfsDumpFileNameAttribute(PATTRIBUTE Attribute)
44 {
45   PRESIDENT_ATTRIBUTE ResAttr;
46   PFILENAME_ATTRIBUTE FileNameAttr;
47
48   DbgPrint("  $FILE_NAME ");
49
50   ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
51 //  DbgPrint(" Length %lu  Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
52
53   FileNameAttr = (PFILENAME_ATTRIBUTE)((PVOID)ResAttr + ResAttr->ValueOffset);
54   DbgPrint(" '%.*S' ", FileNameAttr->NameLength, FileNameAttr->Name);
55 }
56
57
58 VOID
59 NtfsDumpVolumeNameAttribute(PATTRIBUTE Attribute)
60 {
61   PRESIDENT_ATTRIBUTE ResAttr;
62   PWCHAR VolumeName;
63
64   DbgPrint("  $VOLUME_NAME ");
65
66   ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
67 //  DbgPrint(" Length %lu  Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
68
69   VolumeName = (PWCHAR)((PVOID)ResAttr + ResAttr->ValueOffset);
70   DbgPrint(" '%.*S' ", ResAttr->ValueLength/2, VolumeName);
71 }
72
73
74 VOID
75 NtfsDumpVolumeInformationAttribute(PATTRIBUTE Attribute)
76 {
77   PRESIDENT_ATTRIBUTE ResAttr;
78   PVOLINFO_ATTRIBUTE VolInfoAttr;
79
80   DbgPrint("  $VOLUME_INFORMATION ");
81
82   ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
83 //  DbgPrint(" Length %lu  Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
84
85   VolInfoAttr = (PVOLINFO_ATTRIBUTE)((PVOID)ResAttr + ResAttr->ValueOffset);
86   DbgPrint(" NTFS Version %u.%u  Flags 0x%04hx ",
87            VolInfoAttr->MajorVersion,
88            VolInfoAttr->MinorVersion,
89            VolInfoAttr->Flags);
90 }
91
92
93 VOID
94 NtfsDumpAttribute(PATTRIBUTE Attribute)
95 {
96   PNONRESIDENT_ATTRIBUTE NresAttr;
97   PRESIDENT_ATTRIBUTE ResAttr;
98   UNICODE_STRING Name;
99   PUCHAR Ptr;
100   UCHAR RunHeader;
101   ULONG RunLength;
102   ULONG RunStart;
103
104   switch (Attribute->AttributeType)
105     {
106       case AttributeStandardInformation:
107         DbgPrint("  $STANDARD_INFORMATION ");
108         break;
109
110       case AttributeAttributeList:
111         DbgPrint("  $ATTRIBUTE_LIST ");
112         break;
113
114       case AttributeFileName:
115         NtfsDumpFileNameAttribute(Attribute);
116         break;
117
118       case AttributeObjectId:
119         DbgPrint("  $OBJECT_ID ");
120         break;
121
122       case AttributeSecurityDescriptor:
123         DbgPrint("  $SECURITY_DESCRIPTOR ");
124         break;
125
126       case AttributeVolumeName:
127         NtfsDumpVolumeNameAttribute(Attribute);
128         break;
129
130       case AttributeVolumeInformation:
131         NtfsDumpVolumeInformationAttribute(Attribute);
132         break;
133
134       case AttributeData:
135         DbgPrint("  $DATA ");
136         break;
137
138       case AttributeIndexRoot:
139         DbgPrint("  $INDEX_ROOT ");
140         break;
141
142       case AttributeIndexAllocation:
143         DbgPrint("  $INDEX_ALLOCATION ");
144         break;
145
146       case AttributeBitmap:
147         DbgPrint("  $BITMAP ");
148         break;
149
150       case AttributeReparsePoint:
151         DbgPrint("  $REPARSE_POINT ");
152         break;
153
154       case AttributeEAInformation:
155         DbgPrint("  $EA_INFORMATION ");
156         break;
157
158       case AttributeEA:
159         DbgPrint("  $EA ");
160         break;
161
162       case AttributePropertySet:
163         DbgPrint("  $PROPERTY_SET ");
164         break;
165
166       case AttributeLoggedUtilityStream:
167         DbgPrint("  $LOGGED_UTILITY_STREAM ");
168         break;
169
170       default:
171         DbgPrint("  Attribute %lx ",
172                  Attribute->AttributeType);
173         break;
174     }
175
176   if (Attribute->NameLength != 0)
177     {
178       Name.Length = Attribute->NameLength * sizeof(WCHAR);
179       Name.MaximumLength = Name.Length;
180       Name.Buffer = (PWCHAR)((ULONG)Attribute + Attribute->NameOffset);
181
182       DbgPrint("'%wZ' ", &Name);
183     }
184
185   DbgPrint("(%s)\n",
186            Attribute->Nonresident ? "non-resident" : "resident");
187
188   if (Attribute->Nonresident != 0)
189     {
190       NresAttr = (PNONRESIDENT_ATTRIBUTE)Attribute;
191       Ptr = (PUCHAR)((ULONG)NresAttr + NresAttr->RunArrayOffset);
192       while (*Ptr != 0)
193         {
194           RunHeader = *Ptr++;
195
196           switch (RunHeader & 0x0F)
197             {
198               case 1:
199                 RunLength = (ULONG)*Ptr++;
200                 break;
201
202               case 2:
203                 RunLength = *((PUSHORT)Ptr);
204                 Ptr += 2;
205                 break;
206
207               case 3:
208                 RunLength = *Ptr++;
209                 RunLength += *Ptr++ << 8;
210                 RunLength += *Ptr++ << 16;
211                 break;
212
213               case 4:
214                 RunLength = *((PULONG)Ptr);
215                 Ptr += 4;
216                 break;
217
218               default:
219                 DbgPrint("RunLength size of %hu not implemented!\n", RunHeader & 0x0F);
220                 KEBUGCHECK(0);
221             }
222
223           switch (RunHeader >> 4)
224             {
225               case 1:
226                 RunStart = (ULONG)*Ptr;
227                 Ptr++;
228                 break;
229
230               case 2:
231                 RunStart = *((PUSHORT)Ptr);
232                 Ptr += 2;
233                 break;
234
235               case 3:
236                 RunStart = *Ptr++;
237                 RunStart += *Ptr++ << 8;
238                 RunStart += *Ptr++ << 16;
239                 break;
240
241               case 4:
242                 RunStart = *((PULONG)Ptr);
243                 Ptr += 4;
244                 break;
245
246               default:
247                 DbgPrint("RunStart size of %hu not implemented!\n", RunHeader >> 4);
248                 KEBUGCHECK(0);
249             }
250
251           DbgPrint("    AllocatedSize %I64d  DataSize %I64d\n", NresAttr->AllocatedSize, NresAttr->DataSize);
252 //        DbgPrint("    Run: Header %hx  Start %lu  Length %lu\n", RunHeader, RunStart, RunLength);
253           if (RunLength == 1)
254             {
255               DbgPrint("    logical sector %lu (0x%lx)\n", RunStart, RunStart);
256             }
257           else
258             {
259               DbgPrint("    logical sectors %lu-%lu (0x%lx-0x%lx)\n",
260                        RunStart, RunStart + RunLength - 1,
261                        RunStart, RunStart + RunLength - 1);
262             }
263         }
264     }
265
266
267 }
268
269
270 /* EOF */