2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/file/volume.c
5 * PURPOSE: File volume functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 Erik Bos, Alexandre Julliard :
8 DRIVE_IsValid, GetLogicalDriveStringsA,
9 GetLogicalDriveStringsW, GetLogicalDrives
13 //WINE copyright notice:
15 * DOS drives handling functions
17 * Copyright 1993 Erik Bos
18 * Copyright 1996 Alexandre Julliard
21 #undef WIN32_LEAN_AND_MEAN
23 #include <ddk/ntddk.h>
28 #define MAX_DOS_DRIVES 26
30 int DRIVE_IsValid( int drive
)
38 Drives
[0] = 'A' + drive
-1;
39 if ((drive
< 0) || (drive
>= MAX_DOS_DRIVES
)) return 0;
40 if ( CreateFileA(Drives
,GENERIC_READ
,FILE_SHARE_READ
,NULL
,OPEN_EXISTING
,FILE_FLAG_BACKUP_SEMANTICS
|FILE_ATTRIBUTE_DIRECTORY
,NULL
) == -1 ) {
53 GetLogicalDriveStringsA(
60 for (drive
= count
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
61 if (DRIVE_IsValid(drive
)) count
++;
62 if (count
* 4 * sizeof(char) <= nBufferLength
)
65 for (drive
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
66 if (DRIVE_IsValid(drive
))
75 return count
* 4 * sizeof(char);
81 GetLogicalDriveStringsW(
88 for (drive
= count
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
89 if (DRIVE_IsValid(drive
)) count
++;
90 if (count
* 4 * sizeof(WCHAR
) <= nBufferLength
)
93 for (drive
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
94 if (DRIVE_IsValid(drive
))
96 *p
++ = (WCHAR
)('A' + drive
);
103 return count
* 4 * sizeof(WCHAR
);
109 GetLogicalDrives(VOID
)
114 for (drive
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
115 if (DRIVE_IsValid(drive
)) ret
|= (1 << drive
);
124 LPCSTR lpRootPathName
,
125 LPDWORD lpSectorsPerCluster
,
126 LPDWORD lpBytesPerSector
,
127 LPDWORD lpNumberOfFreeClusters
,
128 LPDWORD lpTotalNumberOfClusters
132 WCHAR RootPathNameW
[MAX_PATH
];
134 while ((*lpRootPathName
)!=0 && i
< MAX_PATH
)
136 RootPathNameW
[i
] = *lpRootPathName
;
140 RootPathNameW
[i
] = 0;
141 return GetDiskFreeSpaceW(RootPathNameW
,lpSectorsPerCluster
, lpBytesPerSector
, lpNumberOfFreeClusters
, lpTotalNumberOfClusters
);
147 LPCWSTR lpRootPathName
,
148 LPDWORD lpSectorsPerCluster
,
149 LPDWORD lpBytesPerSector
,
150 LPDWORD lpNumberOfFreeClusters
,
151 LPDWORD lpTotalNumberOfClusters
154 FILE_FS_SIZE_INFORMATION FileFsSize
;
155 IO_STATUS_BLOCK IoStatusBlock
;
165 FILE_ATTRIBUTE_NORMAL
,
169 errCode
= NtQueryVolumeInformationFile(hFile
,&IoStatusBlock
,&FileFsSize
, sizeof(FILE_FS_SIZE_INFORMATION
),FileFsSizeInformation
);
170 if ( !NT_SUCCESS(errCode
) ) {
172 SetLastError(RtlNtStatusToDosError(errCode
));
176 *lpBytesPerSector
= FileFsSize
.BytesPerSector
;
177 *lpSectorsPerCluster
= FileFsSize
.SectorsPerAllocationUnit
;
178 *lpNumberOfFreeClusters
= GET_LARGE_INTEGER_LOW_PART(FileFsSize
.AvailableAllocationUnits
);
179 *lpTotalNumberOfClusters
= GET_LARGE_INTEGER_LOW_PART(FileFsSize
.TotalAllocationUnits
);
187 LPCSTR lpRootPathName
191 WCHAR RootPathNameW
[MAX_PATH
];
193 while ((*lpRootPathName
)!=0 && i
< MAX_PATH
)
195 RootPathNameW
[i
] = *lpRootPathName
;
199 RootPathNameW
[i
] = 0;
200 return GetDriveTypeW(RootPathNameW
);
206 LPCWSTR lpRootPathName
209 FILE_FS_DEVICE_INFORMATION FileFsDevice
;
210 IO_STATUS_BLOCK IoStatusBlock
;
218 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
221 FILE_ATTRIBUTE_NORMAL
,
225 errCode
= NtQueryVolumeInformationFile(hFile
,&IoStatusBlock
,&FileFsDevice
, sizeof(FILE_FS_DEVICE_INFORMATION
),FileFsDeviceInformation
);
226 if ( !NT_SUCCESS(errCode
) ) {
228 SetLastError(RtlNtStatusToDosError(errCode
));
232 return (UINT
)FileFsDevice
.DeviceType
;
240 GetVolumeInformationA(
241 LPCSTR lpRootPathName
,
242 LPSTR lpVolumeNameBuffer
,
243 DWORD nVolumeNameSize
,
244 LPDWORD lpVolumeSerialNumber
,
245 LPDWORD lpMaximumComponentLength
,
246 LPDWORD lpFileSystemFlags
,
247 LPSTR lpFileSystemNameBuffer
,
248 DWORD nFileSystemNameSize
252 WCHAR RootPathNameW
[MAX_PATH
];
253 WCHAR VolumeNameBufferW
[MAX_PATH
];
254 WCHAR FileSystemNameBufferW
[MAX_PATH
];
258 while ((*lpRootPathName
)!=0 && i
< MAX_PATH
)
260 RootPathNameW
[i
] = *lpRootPathName
;
264 RootPathNameW
[i
] = 0;
266 if ( GetVolumeInformationW(RootPathNameW
,
269 lpVolumeSerialNumber
,
270 lpMaximumComponentLength
,
272 FileSystemNameBufferW
,
273 nFileSystemNameSize
) ) {
274 for(i
=0;i
<nVolumeNameSize
;i
++)
275 lpVolumeNameBuffer
[i
] = (CHAR
)VolumeNameBufferW
[i
];
277 for(i
=0;i
<nFileSystemNameSize
;i
++)
278 lpFileSystemNameBuffer
[i
] = (CHAR
)FileSystemNameBufferW
[i
];
289 #define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
291 #define FS_ATTRIBUTE_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_ATTRIBUTE_INFORMATION))
296 GetVolumeInformationW(
297 LPCWSTR lpRootPathName
,
298 LPWSTR lpVolumeNameBuffer
,
299 DWORD nVolumeNameSize
,
300 LPDWORD lpVolumeSerialNumber
,
301 LPDWORD lpMaximumComponentLength
,
302 LPDWORD lpFileSystemFlags
,
303 LPWSTR lpFileSystemNameBuffer
,
304 DWORD nFileSystemNameSize
307 FILE_FS_VOLUME_INFORMATION
*FileFsVolume
;
308 FILE_FS_ATTRIBUTE_INFORMATION
*FileFsAttribute
;
309 IO_STATUS_BLOCK IoStatusBlock
;
310 USHORT Buffer
[FS_VOLUME_BUFFER_SIZE
];
311 USHORT Buffer2
[FS_ATTRIBUTE_BUFFER_SIZE
];
316 FileFsVolume
= (FILE_FS_VOLUME_INFORMATION
*)Buffer
;
317 FileFsAttribute
= (FILE_FS_VOLUME_INFORMATION
*)Buffer2
;
322 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
325 FILE_ATTRIBUTE_NORMAL
,
329 errCode
= NtQueryVolumeInformationFile(hFile
,&IoStatusBlock
,FileFsVolume
, FS_VOLUME_BUFFER_SIZE
,FileFsVolumeInformation
);
330 if ( !NT_SUCCESS(errCode
) ) {
332 SetLastError(RtlNtStatusToDosError(errCode
));
336 memcpy(lpVolumeSerialNumber
, &FileFsVolume
->VolumeSerialNumber
, sizeof(DWORD
));
337 memcpy(lpVolumeNameBuffer
, FileFsVolume
->VolumeLabel
,min(nVolumeNameSize
,MAX_PATH
));
339 errCode
= NtQueryVolumeInformationFile(hFile
,&IoStatusBlock
,FileFsAttribute
, FS_ATTRIBUTE_BUFFER_SIZE
,FileFsAttributeInformation
);
340 if ( !NT_SUCCESS(errCode
) ) {
342 SetLastError(RtlNtStatusToDosError(errCode
));
345 memcpy(lpFileSystemFlags
,&FileFsAttribute
->FileSystemAttributes
,sizeof(DWORD
));
346 memcpy(lpMaximumComponentLength
, &FileFsAttribute
->MaximumComponentNameLength
, sizeof(DWORD
));
347 memcpy(lpFileSystemNameBuffer
, FileFsAttribute
->FileSystemName
,min(nFileSystemNameSize
,MAX_PATH
));
356 LPCSTR lpRootPathName
,
360 WCHAR RootPathNameW
[MAX_PATH
];
361 WCHAR VolumeNameW
[MAX_PATH
];
365 while ((*lpRootPathName
)!=0 && i
< MAX_PATH
)
367 RootPathNameW
[i
] = *lpRootPathName
;
371 RootPathNameW
[i
] = 0;
374 while ((*lpVolumeName
)!=0 && i
< MAX_PATH
)
376 VolumeNameW
[i
] = *lpVolumeName
;
381 return SetVolumeLabelW(RootPathNameW
,VolumeNameW
);
387 LPCWSTR lpRootPathName
,