branch update for HEAD-2003021201
[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 #define NDEBUG
33 #include <debug.h>
34
35 #include "ntfs.h"
36
37
38 /* FUNCTIONS ****************************************************************/
39
40 VOID
41 NtfsDumpFileNameAttribute(PATTRIBUTE Attribute)
42 {
43   PRESIDENT_ATTRIBUTE ResAttr;
44   PFILENAME_ATTRIBUTE FileNameAttr;
45
46   DbgPrint("  $FILE_NAME ");
47
48   ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
49 //  DbgPrint(" Length %lu  Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
50
51   FileNameAttr = (PFILENAME_ATTRIBUTE)((PVOID)ResAttr + ResAttr->ValueOffset);
52   DbgPrint(" '%.*S' ", FileNameAttr->NameLength, FileNameAttr->Name);
53 }
54
55
56 VOID
57 NtfsDumpVolumeNameAttribute(PATTRIBUTE Attribute)
58 {
59   PRESIDENT_ATTRIBUTE ResAttr;
60   PWCHAR VolumeName;
61
62   DbgPrint("  $VOLUME_NAME ");
63
64   ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
65 //  DbgPrint(" Length %lu  Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
66
67   VolumeName = (PWCHAR)((PVOID)ResAttr + ResAttr->ValueOffset);
68   DbgPrint(" '%.*S' ", ResAttr->ValueLength/2, VolumeName);
69 }
70
71
72 VOID
73 NtfsDumpVolumeInformationAttribute(PATTRIBUTE Attribute)
74 {
75   PRESIDENT_ATTRIBUTE ResAttr;
76   PVOLINFO_ATTRIBUTE VolInfoAttr;
77
78   DbgPrint("  $VOLUME_INFORMATION ");
79
80   ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
81 //  DbgPrint(" Length %lu  Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
82
83   VolInfoAttr = (PVOLINFO_ATTRIBUTE)((PVOID)ResAttr + ResAttr->ValueOffset);
84   DbgPrint(" NTFS Version %u.%u  Flags 0x%04hx ",
85            VolInfoAttr->MajorVersion,
86            VolInfoAttr->MinorVersion,
87            VolInfoAttr->Flags);
88 }
89
90
91 VOID
92 NtfsDumpAttribute(PATTRIBUTE Attribute)
93 {
94   PNONRESIDENT_ATTRIBUTE NresAttr;
95   PRESIDENT_ATTRIBUTE ResAttr;
96   UNICODE_STRING Name;
97   PUCHAR Ptr;
98   UCHAR RunHeader;
99   ULONG RunLength;
100   ULONG RunStart;
101
102   switch (Attribute->AttributeType)
103     {
104       case AttributeStandardInformation:
105         DbgPrint("  $STANDARD_INFORMATION ");
106         break;
107
108       case AttributeAttributeList:
109         DbgPrint("  $ATTRIBUTE_LIST ");
110         break;
111
112       case AttributeFileName:
113         NtfsDumpFileNameAttribute(Attribute);
114         break;
115
116       case AttributeObjectId:
117         DbgPrint("  $OBJECT_ID ");
118         break;
119
120       case AttributeSecurityDescriptor:
121         DbgPrint("  $SECURITY_DESCRIPTOR ");
122         break;
123
124       case AttributeVolumeName:
125         NtfsDumpVolumeNameAttribute(Attribute);
126         break;
127
128       case AttributeVolumeInformation:
129         NtfsDumpVolumeInformationAttribute(Attribute);
130         break;
131
132       case AttributeData:
133         DbgPrint("  $DATA ");
134         break;
135
136       case AttributeIndexRoot:
137         DbgPrint("  $INDEX_ROOT ");
138         break;
139
140       case AttributeIndexAllocation:
141         DbgPrint("  $INDEX_ALLOCATION ");
142         break;
143
144       case AttributeBitmap:
145         DbgPrint("  $BITMAP ");
146         break;
147
148       case AttributeReparsePoint:
149         DbgPrint("  $REPARSE_POINT ");
150         break;
151
152       case AttributeEAInformation:
153         DbgPrint("  $EA_INFORMATION ");
154         break;
155
156       case AttributeEA:
157         DbgPrint("  $EA ");
158         break;
159
160       case AttributePropertySet:
161         DbgPrint("  $PROPERTY_SET ");
162         break;
163
164       case AttributeLoggedUtilityStream:
165         DbgPrint("  $LOGGED_UTILITY_STREAM ");
166         break;
167
168       default:
169         DbgPrint("  Attribute %lx ",
170                  Attribute->AttributeType);
171         break;
172     }
173
174   if (Attribute->NameLength != 0)
175     {
176       Name.Length = Attribute->NameLength * sizeof(WCHAR);
177       Name.MaximumLength = Name.Length;
178       Name.Buffer = (PWCHAR)((ULONG)Attribute + Attribute->NameOffset);
179
180       DbgPrint("'%wZ' ", &Name);
181     }
182
183   DbgPrint("(%s)\n",
184            Attribute->Nonresident ? "non-resident" : "resident");
185
186   if (Attribute->Nonresident != 0)
187     {
188       NresAttr = (PNONRESIDENT_ATTRIBUTE)Attribute;
189       Ptr = (PUCHAR)((ULONG)NresAttr + NresAttr->RunArrayOffset);
190       while (*Ptr != 0)
191         {
192           RunHeader = *Ptr++;
193
194           switch (RunHeader & 0x0F)
195             {
196               case 1:
197                 RunLength = (ULONG)*Ptr++;
198                 break;
199
200               case 2:
201                 RunLength = *((PUSHORT)Ptr);
202                 Ptr += 2;
203                 break;
204
205               case 3:
206                 RunLength = *Ptr++;
207                 RunLength += *Ptr++ << 8;
208                 RunLength += *Ptr++ << 16;
209                 break;
210
211               case 4:
212                 RunLength = *((PULONG)Ptr);
213                 Ptr += 4;
214                 break;
215
216               default:
217                 DbgPrint("RunLength size of %hu not implemented!\n", RunHeader & 0x0F);
218                 KeBugCheck(0);
219             }
220
221           switch (RunHeader >> 4)
222             {
223               case 1:
224                 RunStart = (ULONG)*Ptr;
225                 Ptr++;
226                 break;
227
228               case 2:
229                 RunStart = *((PUSHORT)Ptr);
230                 Ptr += 2;
231                 break;
232
233               case 3:
234                 RunStart = *Ptr++;
235                 RunStart += *Ptr++ << 8;
236                 RunStart += *Ptr++ << 16;
237                 break;
238
239               case 4:
240                 RunStart = *((PULONG)Ptr);
241                 Ptr += 4;
242                 break;
243
244               default:
245                 DbgPrint("RunStart size of %hu not implemented!\n", RunHeader >> 4);
246                 KeBugCheck(0);
247             }
248
249           DbgPrint("    AllocatedSize %I64d  DataSize %I64d\n", NresAttr->AllocatedSize, NresAttr->DataSize);
250 //        DbgPrint("    Run: Header %hx  Start %lu  Length %lu\n", RunHeader, RunStart, RunLength);
251           if (RunLength == 1)
252             {
253               DbgPrint("    logical sector %lu (0x%lx)\n", RunStart, RunStart);
254             }
255           else
256             {
257               DbgPrint("    logical sectors %lu-%lu (0x%lx-0x%lx)\n",
258                        RunStart, RunStart + RunLength - 1,
259                        RunStart, RunStart + RunLength - 1);
260             }
261         }
262     }
263
264
265 }
266
267
268 /* EOF */