:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / kernel32 / file / volume.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/file/volume.c
6  * PURPOSE:         File volume functions
7  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
8  *                  Erik Bos, Alexandre Julliard :
9  *                      GetLogicalDriveStringsA,
10  *                      GetLogicalDriveStringsW, GetLogicalDrives
11  * UPDATE HISTORY:
12  *                  Created 01/11/98
13  */
14 //WINE copyright notice:
15 /*
16  * DOS drives handling functions 
17  *
18  * Copyright 1993 Erik Bos
19  * Copyright 1996 Alexandre Julliard
20  */
21
22 #include <ddk/ntddk.h>
23 #include <windows.h>
24 #include <ntos/minmax.h>
25
26 #define NDEBUG
27 #include <kernel32/kernel32.h>
28 #include <kernel32/error.h>
29
30
31 #define MAX_DOS_DRIVES 26
32
33 HANDLE InternalOpenDirW(PWCHAR DirName, BOOLEAN Write)
34 {
35     UNICODE_STRING NtPathU;
36     OBJECT_ATTRIBUTES ObjectAttributes;
37     NTSTATUS errCode;
38     IO_STATUS_BLOCK IoStatusBlock;
39     HANDLE hFile;
40
41     if (!RtlDosPathNameToNtPathName_U ((LPWSTR)DirName,
42                                        &NtPathU,
43                                        NULL,
44                                        NULL))
45     {
46         DPRINT("Invalid path\n");
47         SetLastError(ERROR_BAD_PATHNAME);
48         return INVALID_HANDLE_VALUE;
49     }
50
51     InitializeObjectAttributes(&ObjectAttributes,
52                                &NtPathU,
53                                Write ? FILE_WRITE_ATTRIBUTES : FILE_READ_ATTRIBUTES,
54                                NULL,
55                                NULL);
56
57     errCode = NtCreateFile (&hFile,
58                             Write ? FILE_GENERIC_WRITE : FILE_GENERIC_READ,
59                             &ObjectAttributes,
60                             &IoStatusBlock,
61                             NULL,
62                             0,
63                             FILE_SHARE_READ|FILE_SHARE_WRITE,
64                             FILE_OPEN,
65                             0,
66                             NULL,
67                             0);
68
69     RtlFreeUnicodeString(&NtPathU);
70
71     if (!NT_SUCCESS(errCode))
72     {
73         SetLastErrorByStatus (errCode);
74         return INVALID_HANDLE_VALUE;
75     }
76     return hFile;
77 }
78
79 DWORD STDCALL
80 GetLogicalDriveStringsA(DWORD nBufferLength,
81                         LPSTR lpBuffer)
82 {
83    DWORD drive, count;
84    DWORD dwDriveMap;
85
86    dwDriveMap = SharedUserData->DosDeviceMap;
87
88    for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
89      {
90         if (dwDriveMap & (1<<drive))
91            count++;
92      }
93
94
95    if (count * 4 * sizeof(char) <= nBufferLength)
96      {
97         LPSTR p = lpBuffer;
98
99         for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
100           if (dwDriveMap & (1<<drive))
101           {
102              *p++ = 'A' + drive;
103              *p++ = ':';
104              *p++ = '\\';
105              *p++ = '\0';
106           }
107         *p = '\0';
108      }
109     return (count * 4 * sizeof(char));
110 }
111
112
113 DWORD STDCALL
114 GetLogicalDriveStringsW(DWORD nBufferLength,
115                         LPWSTR lpBuffer)
116 {
117    DWORD drive, count;
118    DWORD dwDriveMap;
119
120    dwDriveMap = SharedUserData->DosDeviceMap;
121
122    for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
123      {
124         if (dwDriveMap & (1<<drive))
125            count++;
126      }
127
128     if (count * 4 * sizeof(WCHAR) <=  nBufferLength)
129     {
130         LPWSTR p = lpBuffer;
131         for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
132             if (dwDriveMap & (1<<drive))
133             {
134                 *p++ = (WCHAR)('A' + drive);
135                 *p++ = (WCHAR)':';
136                 *p++ = (WCHAR)'\\';
137                 *p++ = (WCHAR)'\0';
138             }
139         *p = (WCHAR)'\0';
140     }
141     return (count * 4 * sizeof(WCHAR));
142 }
143
144
145 DWORD STDCALL
146 GetLogicalDrives(VOID)
147 {
148   return(SharedUserData->DosDeviceMap);
149 }
150
151
152 WINBOOL STDCALL
153 GetDiskFreeSpaceA (
154         LPCSTR  lpRootPathName,
155         LPDWORD lpSectorsPerCluster,
156         LPDWORD lpBytesPerSector,
157         LPDWORD lpNumberOfFreeClusters,
158         LPDWORD lpTotalNumberOfClusters
159         )
160 {
161         UNICODE_STRING RootPathNameU;
162         ANSI_STRING RootPathName;
163         WINBOOL Result;
164
165         RtlInitAnsiString (&RootPathName,
166                            (LPSTR)lpRootPathName);
167
168         RtlInitUnicodeString (&RootPathNameU,
169                               NULL);
170
171         if (lpRootPathName)
172         {
173                 /* convert ansi (or oem) string to unicode */
174                 if (bIsFileApiAnsi)
175                         RtlAnsiStringToUnicodeString (&RootPathNameU,
176                                                       &RootPathName,
177                                                       TRUE);
178                 else
179                         RtlOemStringToUnicodeString (&RootPathNameU,
180                                                      &RootPathName,
181                                                      TRUE);
182         }
183
184         Result = GetDiskFreeSpaceW (RootPathNameU.Buffer,
185                                     lpSectorsPerCluster,
186                                     lpBytesPerSector,
187                                     lpNumberOfFreeClusters,
188                                     lpTotalNumberOfClusters);
189
190         if (lpRootPathName)
191         {
192                 RtlFreeHeap (RtlGetProcessHeap (),
193                              0,
194                              RootPathNameU.Buffer);
195         }
196
197         return Result;
198 }
199
200
201 WINBOOL STDCALL
202 GetDiskFreeSpaceW(
203     LPCWSTR lpRootPathName,
204     LPDWORD lpSectorsPerCluster,
205     LPDWORD lpBytesPerSector,
206     LPDWORD lpNumberOfFreeClusters,
207     LPDWORD lpTotalNumberOfClusters
208     )
209 {
210     FILE_FS_SIZE_INFORMATION FileFsSize;
211     IO_STATUS_BLOCK IoStatusBlock;
212     WCHAR RootPathName[MAX_PATH];
213     HANDLE hFile;
214     NTSTATUS errCode;
215
216     if (lpRootPathName)
217     {
218         wcsncpy (RootPathName, lpRootPathName, 3);
219     }
220     else
221     {
222         GetCurrentDirectoryW (MAX_PATH, RootPathName);
223         RootPathName[3] = 0;
224     }
225         
226     if (INVALID_HANDLE_VALUE == (hFile = InternalOpenDirW((PWCHAR)lpRootPathName, FALSE)))
227     {
228         return FALSE;
229     }
230    
231
232     errCode = NtQueryVolumeInformationFile(hFile,
233                                            &IoStatusBlock,
234                                            &FileFsSize,
235                                            sizeof(FILE_FS_SIZE_INFORMATION),
236                                            FileFsSizeInformation);
237     if (!NT_SUCCESS(errCode))
238     {
239         CloseHandle(hFile);
240         SetLastErrorByStatus (errCode);
241         return FALSE;
242     }
243
244     *lpBytesPerSector = FileFsSize.BytesPerSector;
245     *lpSectorsPerCluster = FileFsSize.SectorsPerAllocationUnit;
246     *lpNumberOfFreeClusters = FileFsSize.AvailableAllocationUnits.u.LowPart;
247     *lpTotalNumberOfClusters = FileFsSize.TotalAllocationUnits.u.LowPart;
248     CloseHandle(hFile);
249     return TRUE;
250 }
251
252
253 WINBOOL STDCALL
254 GetDiskFreeSpaceExA (
255         LPCSTR          lpDirectoryName,
256         PULARGE_INTEGER lpFreeBytesAvailableToCaller,
257         PULARGE_INTEGER lpTotalNumberOfBytes,
258         PULARGE_INTEGER lpTotalNumberOfFreeBytes
259         )
260 {
261         UNICODE_STRING DirectoryNameU;
262         ANSI_STRING DirectoryName;
263         WINBOOL Result;
264
265         RtlInitAnsiString (&DirectoryName,
266                            (LPSTR)lpDirectoryName);
267
268         RtlInitUnicodeString (&DirectoryNameU,
269                               NULL);
270
271         if (lpDirectoryName)
272         {
273                 /* convert ansi (or oem) string to unicode */
274                 if (bIsFileApiAnsi)
275                         RtlAnsiStringToUnicodeString (&DirectoryNameU,
276                                                       &DirectoryName,
277                                                       TRUE);
278                 else
279                         RtlOemStringToUnicodeString (&DirectoryNameU,
280                                                      &DirectoryName,
281                                                      TRUE);
282         }
283
284         Result = GetDiskFreeSpaceExW (DirectoryNameU.Buffer,
285                                       lpFreeBytesAvailableToCaller,
286                                       lpTotalNumberOfBytes,
287                                       lpTotalNumberOfFreeBytes);
288
289         if (lpDirectoryName)
290         {
291                 RtlFreeHeap (RtlGetProcessHeap (),
292                              0,
293                              DirectoryNameU.Buffer);
294         }
295
296         return Result;
297 }
298
299
300 WINBOOL STDCALL
301 GetDiskFreeSpaceExW(
302     LPCWSTR lpDirectoryName,
303     PULARGE_INTEGER lpFreeBytesAvailableToCaller,
304     PULARGE_INTEGER lpTotalNumberOfBytes,
305     PULARGE_INTEGER lpTotalNumberOfFreeBytes
306     )
307 {
308     FILE_FS_SIZE_INFORMATION FileFsSize;
309     IO_STATUS_BLOCK IoStatusBlock;
310     ULARGE_INTEGER BytesPerCluster;
311     WCHAR RootPathName[MAX_PATH];
312     HANDLE hFile;
313     NTSTATUS errCode;
314
315     if (lpDirectoryName)
316     {
317         wcsncpy (RootPathName, lpDirectoryName, 3);
318     }
319     else
320     {
321         GetCurrentDirectoryW (MAX_PATH, RootPathName);
322         RootPathName[3] = 0;
323     }
324         
325     if (INVALID_HANDLE_VALUE == (hFile = InternalOpenDirW(lpDirectoryName, FALSE)))
326     {
327         return FALSE;
328     }
329    
330     errCode = NtQueryVolumeInformationFile(hFile,
331                                            &IoStatusBlock,
332                                            &FileFsSize,
333                                            sizeof(FILE_FS_SIZE_INFORMATION),
334                                            FileFsSizeInformation);
335     if (!NT_SUCCESS(errCode))
336     {
337         CloseHandle(hFile);
338         SetLastErrorByStatus (errCode);
339         return FALSE;
340     }
341
342     BytesPerCluster.QuadPart =
343         FileFsSize.BytesPerSector * FileFsSize.SectorsPerAllocationUnit;
344
345     // FIXME: Use quota information
346         if (lpFreeBytesAvailableToCaller)
347         lpFreeBytesAvailableToCaller->QuadPart =
348             BytesPerCluster.QuadPart * FileFsSize.AvailableAllocationUnits.QuadPart;
349         
350         if (lpTotalNumberOfBytes)
351         lpTotalNumberOfBytes->QuadPart =
352             BytesPerCluster.QuadPart * FileFsSize.TotalAllocationUnits.QuadPart;
353         if (lpTotalNumberOfFreeBytes)
354         lpTotalNumberOfFreeBytes->QuadPart =
355             BytesPerCluster.QuadPart * FileFsSize.AvailableAllocationUnits.QuadPart;
356
357     CloseHandle(hFile);
358     return TRUE;
359 }
360
361
362 UINT STDCALL
363 GetDriveTypeA(LPCSTR lpRootPathName)
364 {
365         UNICODE_STRING RootPathNameU;
366         ANSI_STRING RootPathName;
367         UINT Result;
368
369         RtlInitAnsiString (&RootPathName,
370                            (LPSTR)lpRootPathName);
371
372         /* convert ansi (or oem) string to unicode */
373         if (bIsFileApiAnsi)
374                 RtlAnsiStringToUnicodeString (&RootPathNameU,
375                                               &RootPathName,
376                                               TRUE);
377         else
378                 RtlOemStringToUnicodeString (&RootPathNameU,
379                                              &RootPathName,
380                                              TRUE);
381
382         Result = GetDriveTypeW (RootPathNameU.Buffer);
383
384         RtlFreeHeap (RtlGetProcessHeap (),
385                      0,
386                      RootPathNameU.Buffer);
387
388         return Result;
389 }
390
391 UINT STDCALL
392 GetDriveTypeW(LPCWSTR lpRootPathName)
393 {
394         FILE_FS_DEVICE_INFORMATION FileFsDevice;
395         IO_STATUS_BLOCK IoStatusBlock;
396
397         HANDLE hFile;
398         NTSTATUS errCode;
399
400         hFile = InternalOpenDirW(lpRootPathName, FALSE);
401         if (hFile == INVALID_HANDLE_VALUE)
402         {
403             return 0;
404         }
405
406         errCode = NtQueryVolumeInformationFile (hFile,
407                                                 &IoStatusBlock,
408                                                 &FileFsDevice,
409                                                 sizeof(FILE_FS_DEVICE_INFORMATION),
410                                                 FileFsDeviceInformation);
411         if (!NT_SUCCESS(errCode))
412         {
413                 CloseHandle(hFile);
414                 SetLastErrorByStatus (errCode);
415                 return 0;
416         }
417         CloseHandle(hFile);
418         return (UINT)FileFsDevice.DeviceType;
419 }
420
421
422 WINBOOL STDCALL
423 GetVolumeInformationA(
424         LPCSTR  lpRootPathName,
425         LPSTR   lpVolumeNameBuffer,
426         DWORD   nVolumeNameSize,
427         LPDWORD lpVolumeSerialNumber,
428         LPDWORD lpMaximumComponentLength,
429         LPDWORD lpFileSystemFlags,
430         LPSTR   lpFileSystemNameBuffer,
431         DWORD   nFileSystemNameSize
432         )
433 {
434         UNICODE_STRING RootPathNameU;
435         UNICODE_STRING FileSystemNameU;
436         UNICODE_STRING VolumeNameU;
437         ANSI_STRING RootPathName;
438         ANSI_STRING VolumeName;
439         ANSI_STRING FileSystemName;
440         WINBOOL Result;
441
442         RtlInitAnsiString (&RootPathName,
443                            (LPSTR)lpRootPathName);
444
445         /* convert ansi (or oem) string to unicode */
446         if (bIsFileApiAnsi)
447                 RtlAnsiStringToUnicodeString (&RootPathNameU,
448                                               &RootPathName,
449                                               TRUE);
450         else
451                 RtlOemStringToUnicodeString (&RootPathNameU,
452                                              &RootPathName,
453                                              TRUE);
454
455         VolumeNameU.Length = 0;
456         VolumeNameU.MaximumLength = nVolumeNameSize * sizeof(WCHAR);
457         VolumeNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
458                                               0,
459                                               VolumeNameU.MaximumLength);
460
461         FileSystemNameU.Length = 0;
462         FileSystemNameU.MaximumLength = nFileSystemNameSize * sizeof(WCHAR);
463         FileSystemNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
464                                                   0,
465                                                   FileSystemNameU.MaximumLength);
466
467         Result = GetVolumeInformationW (RootPathNameU.Buffer,
468                                         VolumeNameU.Buffer,
469                                         nVolumeNameSize,
470                                         lpVolumeSerialNumber,
471                                         lpMaximumComponentLength,
472                                         lpFileSystemFlags,
473                                         FileSystemNameU.Buffer,
474                                         nFileSystemNameSize);
475
476         if (Result)
477         {
478                 VolumeNameU.Length = wcslen(VolumeNameU.Buffer) * sizeof(WCHAR);
479                 VolumeName.Length = 0;
480                 VolumeName.MaximumLength = nVolumeNameSize;
481                 VolumeName.Buffer = lpVolumeNameBuffer;
482
483                 FileSystemNameU.Length = wcslen(FileSystemNameU.Buffer) * sizeof(WCHAR);
484                 FileSystemName.Length = 0;
485                 FileSystemName.MaximumLength = nFileSystemNameSize;
486                 FileSystemName.Buffer = lpFileSystemNameBuffer;
487
488                 /* convert unicode strings to ansi (or oem) */
489                 if (bIsFileApiAnsi)
490                 {
491                         RtlUnicodeStringToAnsiString (&VolumeName,
492                                                       &VolumeNameU,
493                                                       FALSE);
494                         RtlUnicodeStringToAnsiString (&FileSystemName,
495                                                       &FileSystemNameU,
496                                                       FALSE);
497                 }
498                 else
499                 {
500                         RtlUnicodeStringToOemString (&VolumeName,
501                                                      &VolumeNameU,
502                                                      FALSE);
503                         RtlUnicodeStringToOemString (&FileSystemName,
504                                                      &FileSystemNameU,
505                                                      FALSE);
506                 }
507         }
508
509         RtlFreeHeap (RtlGetProcessHeap (),
510                      0,
511                      RootPathNameU.Buffer);
512         RtlFreeHeap (RtlGetProcessHeap (),
513                      0,
514                      VolumeNameU.Buffer);
515         RtlFreeHeap (RtlGetProcessHeap (),
516                      0,
517                      FileSystemNameU.Buffer);
518
519         return Result;
520 }
521
522
523
524
525 #define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
526
527 #define FS_ATTRIBUTE_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_ATTRIBUTE_INFORMATION))
528
529
530 WINBOOL STDCALL
531 GetVolumeInformationW(
532     LPCWSTR lpRootPathName,
533     LPWSTR lpVolumeNameBuffer,
534     DWORD nVolumeNameSize,
535     LPDWORD lpVolumeSerialNumber,
536     LPDWORD lpMaximumComponentLength,
537     LPDWORD lpFileSystemFlags,
538     LPWSTR lpFileSystemNameBuffer,
539     DWORD nFileSystemNameSize
540     )
541 {
542         PFILE_FS_VOLUME_INFORMATION FileFsVolume;
543         PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute;
544         IO_STATUS_BLOCK IoStatusBlock;
545         OBJECT_ATTRIBUTES ObjectAttributes;
546         USHORT Buffer[FS_VOLUME_BUFFER_SIZE];
547         USHORT Buffer2[FS_ATTRIBUTE_BUFFER_SIZE];
548
549         HANDLE hFile;
550         NTSTATUS errCode;
551
552         FileFsVolume = (PFILE_FS_VOLUME_INFORMATION)Buffer;
553         FileFsAttribute = (PFILE_FS_ATTRIBUTE_INFORMATION)Buffer2;
554
555         DPRINT("FileFsVolume %p\n", FileFsVolume);
556         DPRINT("FileFsAttribute %p\n", FileFsAttribute);
557
558         hFile = InternalOpenDirW(lpRootPathName, FALSE);
559         if (hFile == INVALID_HANDLE_VALUE)
560         {
561             return FALSE;
562         }
563
564         DPRINT("hFile: %x\n", hFile);
565         errCode = NtQueryVolumeInformationFile(hFile,
566                                                &IoStatusBlock,
567                                                FileFsVolume,
568                                                FS_VOLUME_BUFFER_SIZE,
569                                                FileFsVolumeInformation);
570         if ( !NT_SUCCESS(errCode) ) {
571                 DPRINT("Status: %x\n", errCode);
572                 CloseHandle(hFile);
573                 SetLastErrorByStatus (errCode);
574                 return FALSE;
575         }
576
577         if (lpVolumeSerialNumber)
578                 *lpVolumeSerialNumber = FileFsVolume->VolumeSerialNumber;
579
580         if (lpVolumeNameBuffer)
581                 wcsncpy (lpVolumeNameBuffer,
582                          FileFsVolume->VolumeLabel,
583                          min(nVolumeNameSize,MAX_PATH));
584
585         errCode = NtQueryVolumeInformationFile (hFile,
586                                                 &IoStatusBlock,
587                                                 FileFsAttribute,
588                                                 FS_ATTRIBUTE_BUFFER_SIZE,
589                                                 FileFsAttributeInformation);
590         if (!NT_SUCCESS(errCode))
591         {
592                 DPRINT("Status: %x\n", errCode);
593                 CloseHandle(hFile);
594                 SetLastErrorByStatus (errCode);
595                 return FALSE;
596         }
597
598         if (lpFileSystemFlags)
599                 *lpFileSystemFlags = FileFsAttribute->FileSystemAttributes;
600         if (lpMaximumComponentLength)
601                 *lpMaximumComponentLength = FileFsAttribute->MaximumComponentNameLength;
602         if (lpFileSystemNameBuffer)
603                 wcsncpy(lpFileSystemNameBuffer, FileFsAttribute->FileSystemName,min(nFileSystemNameSize,MAX_PATH));
604
605         CloseHandle(hFile);
606         return TRUE;
607 }
608
609
610 WINBOOL
611 STDCALL
612 SetVolumeLabelA (
613         LPCSTR  lpRootPathName,
614         LPCSTR  lpVolumeName
615         )
616 {
617         UNICODE_STRING RootPathNameU;
618         ANSI_STRING RootPathName;
619         UNICODE_STRING VolumeNameU;
620         ANSI_STRING VolumeName;
621         WINBOOL Result;
622
623         RtlInitAnsiString (&RootPathName,
624                            (LPSTR)lpRootPathName);
625         RtlInitAnsiString (&VolumeName,
626                            (LPSTR)lpVolumeName);
627
628         /* convert ansi (or oem) strings to unicode */
629         if (bIsFileApiAnsi)
630         {
631                 RtlAnsiStringToUnicodeString (&RootPathNameU,
632                                               &RootPathName,
633                                               TRUE);
634                 RtlAnsiStringToUnicodeString (&VolumeNameU,
635                                               &VolumeName,
636                                               TRUE);
637         }
638         else
639         {
640                 RtlOemStringToUnicodeString (&RootPathNameU,
641                                              &RootPathName,
642                                              TRUE);
643                 RtlOemStringToUnicodeString (&VolumeNameU,
644                                              &VolumeName,
645                                              TRUE);
646         }
647
648         Result = SetVolumeLabelW (RootPathNameU.Buffer,
649                                   VolumeNameU.Buffer);
650
651         RtlFreeHeap (RtlGetProcessHeap (),
652                      0,
653                      RootPathNameU.Buffer);
654         RtlFreeHeap (RtlGetProcessHeap (),
655                      0,
656                      VolumeNameU.Buffer);
657
658         return Result;
659 }
660
661
662 WINBOOL STDCALL
663 SetVolumeLabelW(LPCWSTR lpRootPathName,
664                 LPCWSTR lpVolumeName)
665 {
666    PFILE_FS_LABEL_INFORMATION LabelInfo;
667    IO_STATUS_BLOCK IoStatusBlock;
668    ULONG LabelLength;
669    HANDLE hFile;
670    NTSTATUS Status;
671    
672    LabelLength = wcslen(lpVolumeName) * sizeof(WCHAR);
673    LabelInfo = RtlAllocateHeap(RtlGetProcessHeap(),
674                                0,
675                                sizeof(FILE_FS_LABEL_INFORMATION) +
676                                LabelLength);
677    LabelInfo->VolumeLabelLength = LabelLength;
678    wcscpy(LabelInfo->VolumeLabel,
679           lpVolumeName);
680    
681    if (INVALID_HANDLE_VALUE == (hFile = InternalOpenDirW(lpRootPathName, TRUE)))
682    {
683         return FALSE;
684    }
685    
686    Status = NtSetVolumeInformationFile(hFile,
687                                        &IoStatusBlock,
688                                        LabelInfo,
689                                        sizeof(FILE_FS_LABEL_INFORMATION) +
690                                        LabelLength,
691                                        FileFsLabelInformation);
692
693    RtlFreeHeap(RtlGetProcessHeap(),
694                0,
695                LabelInfo);
696
697    if (!NT_SUCCESS(Status))
698      {
699         DPRINT("Status: %x\n", Status);
700         CloseHandle(hFile);
701         SetLastErrorByStatus(Status);
702         return FALSE;
703      }
704
705    CloseHandle(hFile);
706    return TRUE;
707 }
708
709 /* EOF */