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
22 #include <ddk/ntddk.h>
27 #include <kernel32/kernel32.h>
30 #define MAX_DOS_DRIVES 26
33 int DRIVE_IsValid( int drive
)
41 Drives
[0] = 'A' + drive
-1;
42 if ((drive
< 0) || (drive
>= MAX_DOS_DRIVES
)) return 0;
43 if ( CreateFileA(Drives
,GENERIC_READ
,FILE_SHARE_READ
,NULL
,OPEN_EXISTING
,FILE_FLAG_BACKUP_SEMANTICS
|FILE_ATTRIBUTE_DIRECTORY
,NULL
) == -1 ) {
56 GetLogicalDriveStringsA(
63 for (drive
= count
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
64 if (DRIVE_IsValid(drive
)) count
++;
65 if (count
* 4 * sizeof(char) <= nBufferLength
)
68 for (drive
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
69 if (DRIVE_IsValid(drive
))
78 return count
* 4 * sizeof(char);
84 GetLogicalDriveStringsW(
91 for (drive
= count
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
92 if (DRIVE_IsValid(drive
)) count
++;
93 if (count
* 4 * sizeof(WCHAR
) <= nBufferLength
)
96 for (drive
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
97 if (DRIVE_IsValid(drive
))
99 *p
++ = (WCHAR
)('A' + drive
);
106 return count
* 4 * sizeof(WCHAR
);
112 GetLogicalDrives(VOID
)
117 for (drive
= 0; drive
< MAX_DOS_DRIVES
; drive
++)
118 if (DRIVE_IsValid(drive
)) ret
|= (1 << drive
);
127 LPCSTR lpRootPathName
,
128 LPDWORD lpSectorsPerCluster
,
129 LPDWORD lpBytesPerSector
,
130 LPDWORD lpNumberOfFreeClusters
,
131 LPDWORD lpTotalNumberOfClusters
135 WCHAR RootPathNameW
[MAX_PATH
];
137 while ((*lpRootPathName
)!=0 && i
< MAX_PATH
)
139 RootPathNameW
[i
] = *lpRootPathName
;
143 RootPathNameW
[i
] = 0;
144 return GetDiskFreeSpaceW(RootPathNameW
,lpSectorsPerCluster
, lpBytesPerSector
, lpNumberOfFreeClusters
, lpTotalNumberOfClusters
);
150 LPCWSTR lpRootPathName
,
151 LPDWORD lpSectorsPerCluster
,
152 LPDWORD lpBytesPerSector
,
153 LPDWORD lpNumberOfFreeClusters
,
154 LPDWORD lpTotalNumberOfClusters
157 FILE_FS_SIZE_INFORMATION FileFsSize
;
158 IO_STATUS_BLOCK IoStatusBlock
;
168 FILE_ATTRIBUTE_NORMAL
,
172 errCode
= NtQueryVolumeInformationFile(hFile
,&IoStatusBlock
,&FileFsSize
, sizeof(FILE_FS_SIZE_INFORMATION
),FileFsSizeInformation
);
173 if ( !NT_SUCCESS(errCode
) ) {
175 SetLastError(RtlNtStatusToDosError(errCode
));
179 *lpBytesPerSector
= FileFsSize
.BytesPerSector
;
180 *lpSectorsPerCluster
= FileFsSize
.SectorsPerAllocationUnit
;
181 *lpNumberOfFreeClusters
= FileFsSize
.AvailableAllocationUnits
.LowPart
;
182 *lpTotalNumberOfClusters
= FileFsSize
.TotalAllocationUnits
.LowPart
;
190 LPCSTR lpRootPathName
194 WCHAR RootPathNameW
[MAX_PATH
];
196 while ((*lpRootPathName
)!=0 && i
< MAX_PATH
)
198 RootPathNameW
[i
] = *lpRootPathName
;
202 RootPathNameW
[i
] = 0;
203 return GetDriveTypeW(RootPathNameW
);
209 LPCWSTR lpRootPathName
212 FILE_FS_DEVICE_INFORMATION FileFsDevice
;
213 IO_STATUS_BLOCK IoStatusBlock
;
221 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
224 FILE_ATTRIBUTE_NORMAL
,
228 errCode
= NtQueryVolumeInformationFile(hFile
,&IoStatusBlock
,&FileFsDevice
, sizeof(FILE_FS_DEVICE_INFORMATION
),FileFsDeviceInformation
);
229 if ( !NT_SUCCESS(errCode
) ) {
231 SetLastError(RtlNtStatusToDosError(errCode
));
235 return (UINT
)FileFsDevice
.DeviceType
;
243 GetVolumeInformationA(
244 LPCSTR lpRootPathName
,
245 LPSTR lpVolumeNameBuffer
,
246 DWORD nVolumeNameSize
,
247 LPDWORD lpVolumeSerialNumber
,
248 LPDWORD lpMaximumComponentLength
,
249 LPDWORD lpFileSystemFlags
,
250 LPSTR lpFileSystemNameBuffer
,
251 DWORD nFileSystemNameSize
255 WCHAR RootPathNameW
[MAX_PATH
];
256 WCHAR VolumeNameBufferW
[MAX_PATH
];
257 WCHAR FileSystemNameBufferW
[MAX_PATH
];
261 while ((*lpRootPathName
)!=0 && i
< MAX_PATH
)
263 RootPathNameW
[i
] = *lpRootPathName
;
267 RootPathNameW
[i
] = 0;
269 if ( GetVolumeInformationW(RootPathNameW
,
272 lpVolumeSerialNumber
,
273 lpMaximumComponentLength
,
275 FileSystemNameBufferW
,
276 nFileSystemNameSize
) ) {
277 for(i
=0;i
<nVolumeNameSize
;i
++)
278 lpVolumeNameBuffer
[i
] = (CHAR
)VolumeNameBufferW
[i
];
280 for(i
=0;i
<nFileSystemNameSize
;i
++)
281 lpFileSystemNameBuffer
[i
] = (CHAR
)FileSystemNameBufferW
[i
];
292 #define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
294 #define FS_ATTRIBUTE_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_ATTRIBUTE_INFORMATION))
299 GetVolumeInformationW(
300 LPCWSTR lpRootPathName
,
301 LPWSTR lpVolumeNameBuffer
,
302 DWORD nVolumeNameSize
,
303 LPDWORD lpVolumeSerialNumber
,
304 LPDWORD lpMaximumComponentLength
,
305 LPDWORD lpFileSystemFlags
,
306 LPWSTR lpFileSystemNameBuffer
,
307 DWORD nFileSystemNameSize
310 PFILE_FS_VOLUME_INFORMATION FileFsVolume
;
311 PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute
;
312 IO_STATUS_BLOCK IoStatusBlock
;
313 USHORT Buffer
[FS_VOLUME_BUFFER_SIZE
];
314 USHORT Buffer2
[FS_ATTRIBUTE_BUFFER_SIZE
];
319 FileFsVolume
= (PFILE_FS_VOLUME_INFORMATION
)Buffer
;
320 FileFsAttribute
= (PFILE_FS_ATTRIBUTE_INFORMATION
)Buffer2
;
322 DPRINT("FileFsVolume %p\n", FileFsVolume
);
323 DPRINT("FileFsAttribute %p\n", FileFsAttribute
);
325 hFile
= CreateFileW(lpRootPathName
,
326 FILE_READ_ATTRIBUTES
,
327 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
330 FILE_ATTRIBUTE_NORMAL
,
333 DPRINT("hFile: %x\n", hFile
);
334 errCode
= NtQueryVolumeInformationFile(hFile
,
337 FS_VOLUME_BUFFER_SIZE
,
338 FileFsVolumeInformation
);
339 if ( !NT_SUCCESS(errCode
) ) {
340 DPRINT("Status: %x\n", errCode
);
342 SetLastError(RtlNtStatusToDosError(errCode
));
346 if (lpVolumeSerialNumber
)
347 *lpVolumeSerialNumber
= FileFsVolume
->VolumeSerialNumber
;
349 if (lpVolumeNameBuffer
)
350 wcsncpy(lpVolumeNameBuffer
, FileFsVolume
->VolumeLabel
,min(nVolumeNameSize
,MAX_PATH
));
352 errCode
= NtQueryVolumeInformationFile(hFile
,&IoStatusBlock
,FileFsAttribute
, FS_ATTRIBUTE_BUFFER_SIZE
,FileFsAttributeInformation
);
353 if ( !NT_SUCCESS(errCode
) ) {
354 DPRINT("Status: %x\n", errCode
);
356 SetLastError(RtlNtStatusToDosError(errCode
));
360 if (lpFileSystemFlags
)
361 *lpFileSystemFlags
= FileFsAttribute
->FileSystemAttributes
;
362 if (lpMaximumComponentLength
)
363 *lpMaximumComponentLength
= FileFsAttribute
->MaximumComponentNameLength
;
364 if (lpFileSystemNameBuffer
)
365 wcsncpy(lpFileSystemNameBuffer
, FileFsAttribute
->FileSystemName
,min(nFileSystemNameSize
,MAX_PATH
));
374 LPCSTR lpRootPathName
,
378 WCHAR RootPathNameW
[MAX_PATH
];
379 WCHAR VolumeNameW
[MAX_PATH
];
383 while ((*lpRootPathName
)!=0 && i
< MAX_PATH
)
385 RootPathNameW
[i
] = *lpRootPathName
;
389 RootPathNameW
[i
] = 0;
392 while ((*lpVolumeName
)!=0 && i
< MAX_PATH
)
394 VolumeNameW
[i
] = *lpVolumeName
;
399 return SetVolumeLabelW(RootPathNameW
,VolumeNameW
);
405 LPCWSTR lpRootPathName
,