Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
d1051870
Commit
d1051870
authored
Apr 17, 2004
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reimplemented GetDiskFreeSpaceW and GetDiskFreeSpaceExW on top of the
corresponding ntdll functions.
parent
a9832be1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
165 additions
and
262 deletions
+165
-262
volume.c
dlls/kernel/volume.c
+165
-0
drive.c
files/drive.c
+0
-262
No files found.
dlls/kernel/volume.c
View file @
d1051870
...
...
@@ -148,6 +148,40 @@ static char *get_dos_device_path( LPCWSTR name )
}
/* open a handle to a device root */
static
BOOL
open_device_root
(
LPCWSTR
root
,
HANDLE
*
handle
)
{
static
const
WCHAR
default_rootW
[]
=
{
'\\'
,
0
};
UNICODE_STRING
nt_name
;
OBJECT_ATTRIBUTES
attr
;
IO_STATUS_BLOCK
io
;
NTSTATUS
status
;
if
(
!
root
)
root
=
default_rootW
;
if
(
!
RtlDosPathNameToNtPathName_U
(
root
,
&
nt_name
,
NULL
,
NULL
))
{
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
FALSE
;
}
attr
.
Length
=
sizeof
(
attr
);
attr
.
RootDirectory
=
0
;
attr
.
Attributes
=
OBJ_CASE_INSENSITIVE
;
attr
.
ObjectName
=
&
nt_name
;
attr
.
SecurityDescriptor
=
NULL
;
attr
.
SecurityQualityOfService
=
NULL
;
status
=
NtOpenFile
(
handle
,
0
,
&
attr
,
&
io
,
0
,
FILE_DIRECTORY_FILE
|
FILE_SYNCHRONOUS_IO_NONALERT
);
RtlFreeUnicodeString
(
&
nt_name
);
if
(
status
!=
STATUS_SUCCESS
)
{
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
return
FALSE
;
}
return
TRUE
;
}
/* create symlinks for the DOS drives; helper for VOLUME_CreateDevices */
static
int
create_drives
(
void
)
{
...
...
@@ -1206,3 +1240,134 @@ DWORD WINAPI QueryDosDeviceA( LPCSTR devname, LPSTR target, DWORD bufsize )
HeapFree
(
GetProcessHeap
(),
0
,
targetW
);
return
ret
;
}
/***********************************************************************
* GetDiskFreeSpaceExW (KERNEL32.@)
*
* This function is used to acquire the size of the available and
* total space on a logical volume.
*
* RETURNS
*
* Zero on failure, nonzero upon success. Use GetLastError to obtain
* detailed error information.
*
*/
BOOL
WINAPI
GetDiskFreeSpaceExW
(
LPCWSTR
root
,
PULARGE_INTEGER
avail
,
PULARGE_INTEGER
total
,
PULARGE_INTEGER
totalfree
)
{
FILE_FS_SIZE_INFORMATION
info
;
IO_STATUS_BLOCK
io
;
NTSTATUS
status
;
HANDLE
handle
;
UINT
units
;
TRACE
(
"%s,%p,%p,%p
\n
"
,
debugstr_w
(
root
),
avail
,
total
,
totalfree
);
if
(
!
open_device_root
(
root
,
&
handle
))
return
FALSE
;
status
=
NtQueryVolumeInformationFile
(
handle
,
&
io
,
&
info
,
sizeof
(
info
),
FileFsSizeInformation
);
NtClose
(
handle
);
if
(
status
!=
STATUS_SUCCESS
)
{
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
return
FALSE
;
}
units
=
info
.
SectorsPerAllocationUnit
*
info
.
BytesPerSector
;
if
(
total
)
total
->
QuadPart
=
info
.
TotalAllocationUnits
.
QuadPart
*
units
;
if
(
totalfree
)
totalfree
->
QuadPart
=
info
.
AvailableAllocationUnits
.
QuadPart
*
units
;
/* FIXME: this one should take quotas into account */
if
(
avail
)
avail
->
QuadPart
=
info
.
AvailableAllocationUnits
.
QuadPart
*
units
;
return
TRUE
;
}
/***********************************************************************
* GetDiskFreeSpaceExA (KERNEL32.@)
*/
BOOL
WINAPI
GetDiskFreeSpaceExA
(
LPCSTR
root
,
PULARGE_INTEGER
avail
,
PULARGE_INTEGER
total
,
PULARGE_INTEGER
totalfree
)
{
UNICODE_STRING
rootW
;
BOOL
ret
;
if
(
root
)
RtlCreateUnicodeStringFromAsciiz
(
&
rootW
,
root
);
else
rootW
.
Buffer
=
NULL
;
ret
=
GetDiskFreeSpaceExW
(
rootW
.
Buffer
,
avail
,
total
,
totalfree
);
RtlFreeUnicodeString
(
&
rootW
);
return
ret
;
}
/***********************************************************************
* GetDiskFreeSpaceW (KERNEL32.@)
*/
BOOL
WINAPI
GetDiskFreeSpaceW
(
LPCWSTR
root
,
LPDWORD
cluster_sectors
,
LPDWORD
sector_bytes
,
LPDWORD
free_clusters
,
LPDWORD
total_clusters
)
{
FILE_FS_SIZE_INFORMATION
info
;
IO_STATUS_BLOCK
io
;
NTSTATUS
status
;
HANDLE
handle
;
UINT
units
;
TRACE
(
"%s,%p,%p,%p,%p
\n
"
,
debugstr_w
(
root
),
cluster_sectors
,
sector_bytes
,
free_clusters
,
total_clusters
);
if
(
!
open_device_root
(
root
,
&
handle
))
return
FALSE
;
status
=
NtQueryVolumeInformationFile
(
handle
,
&
io
,
&
info
,
sizeof
(
info
),
FileFsSizeInformation
);
NtClose
(
handle
);
if
(
status
!=
STATUS_SUCCESS
)
{
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
return
FALSE
;
}
units
=
info
.
SectorsPerAllocationUnit
*
info
.
BytesPerSector
;
/* cap the size and available at 2GB as per specs */
if
(
info
.
AvailableAllocationUnits
.
QuadPart
*
units
>
0x7fffffff
)
info
.
AvailableAllocationUnits
.
QuadPart
=
0x7fffffff
/
units
;
if
(
info
.
TotalAllocationUnits
.
QuadPart
*
units
>
0x7fffffff
)
info
.
TotalAllocationUnits
.
QuadPart
=
0x7fffffff
/
units
;
if
(
cluster_sectors
)
*
cluster_sectors
=
info
.
SectorsPerAllocationUnit
;
if
(
sector_bytes
)
*
sector_bytes
=
info
.
BytesPerSector
;
if
(
free_clusters
)
*
free_clusters
=
info
.
AvailableAllocationUnits
.
u
.
LowPart
;
if
(
total_clusters
)
*
total_clusters
=
info
.
TotalAllocationUnits
.
u
.
LowPart
;
return
TRUE
;
}
/***********************************************************************
* GetDiskFreeSpaceA (KERNEL32.@)
*/
BOOL
WINAPI
GetDiskFreeSpaceA
(
LPCSTR
root
,
LPDWORD
cluster_sectors
,
LPDWORD
sector_bytes
,
LPDWORD
free_clusters
,
LPDWORD
total_clusters
)
{
UNICODE_STRING
rootW
;
BOOL
ret
=
FALSE
;
if
(
root
)
{
if
(
!
RtlCreateUnicodeStringFromAsciiz
(
&
rootW
,
root
))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
}
else
rootW
.
Buffer
=
NULL
;
ret
=
GetDiskFreeSpaceW
(
rootW
.
Buffer
,
cluster_sectors
,
sector_bytes
,
free_clusters
,
total_clusters
);
RtlFreeUnicodeString
(
&
rootW
);
return
ret
;
}
files/drive.c
View file @
d1051870
...
...
@@ -39,9 +39,6 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_STATVFS_H
# include <sys/statvfs.h>
#endif
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
...
...
@@ -644,35 +641,6 @@ int DRIVE_Chdir( int drive, LPCWSTR path )
/***********************************************************************
* DRIVE_GetFreeSpace
*/
static
int
DRIVE_GetFreeSpace
(
int
drive
,
PULARGE_INTEGER
size
,
PULARGE_INTEGER
available
)
{
struct
statvfs
info
;
if
(
!
DRIVE_IsValid
(
drive
))
{
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
0
;
}
if
(
statvfs
(
DOSDrives
[
drive
].
root
,
&
info
)
<
0
)
{
FILE_SetDosError
();
WARN
(
"cannot do statvfs(%s)
\n
"
,
DOSDrives
[
drive
].
root
);
return
0
;
}
size
->
QuadPart
=
RtlEnlargedUnsignedMultiply
(
info
.
f_frsize
,
info
.
f_blocks
);
if
(
DOSDrives
[
drive
].
type
==
DRIVE_CDROM
)
available
->
QuadPart
=
0
;
/* ALWAYS 0, even if no real CD-ROM mounted there !! */
else
available
->
QuadPart
=
RtlEnlargedUnsignedMultiply
(
info
.
f_frsize
,
info
.
f_bavail
);
return
1
;
}
/***********************************************************************
* DRIVE_GetCurrentDirectory
* Returns "X:\\path\\etc\\".
*
...
...
@@ -729,236 +697,6 @@ WCHAR *DRIVE_BuildEnv(void)
/***********************************************************************
* GetDiskFreeSpaceW (KERNEL32.@)
*
* Fails if expression resulting from current drive's dir and "root"
* is not a root dir of the target drive.
*
* UNDOC: setting some LPDWORDs to NULL is perfectly possible
* if the corresponding info is unneeded.
*
* FIXME: needs to support UNC names from Win95 OSR2 on.
*
* Behaviour under Win95a:
* CurrDir root result
* "E:\\TEST" "E:" FALSE
* "E:\\" "E:" TRUE
* "E:\\" "E" FALSE
* "E:\\" "\\" TRUE
* "E:\\TEST" "\\" TRUE
* "E:\\TEST" ":\\" FALSE
* "E:\\TEST" "E:\\" TRUE
* "E:\\TEST" "" FALSE
* "E:\\" "" FALSE (!)
* "E:\\" 0x0 TRUE
* "E:\\TEST" 0x0 TRUE (!)
* "E:\\TEST" "C:" TRUE (when CurrDir of "C:" set to "\\")
* "E:\\TEST" "C:" FALSE (when CurrDir of "C:" set to "\\TEST")
*/
BOOL
WINAPI
GetDiskFreeSpaceW
(
LPCWSTR
root
,
LPDWORD
cluster_sectors
,
LPDWORD
sector_bytes
,
LPDWORD
free_clusters
,
LPDWORD
total_clusters
)
{
int
drive
,
sec_size
;
ULARGE_INTEGER
size
,
available
;
LPCWSTR
path
;
DWORD
cluster_sec
;
TRACE
(
"%s,%p,%p,%p,%p
\n
"
,
debugstr_w
(
root
),
cluster_sectors
,
sector_bytes
,
free_clusters
,
total_clusters
);
if
(
!
root
||
root
[
0
]
==
'\\'
||
root
[
0
]
==
'/'
)
drive
=
DRIVE_GetCurrentDrive
();
else
if
(
root
[
0
]
&&
root
[
1
]
==
':'
)
/* root contains drive tag */
{
drive
=
toupperW
(
root
[
0
])
-
'A'
;
path
=
&
root
[
2
];
if
(
path
[
0
]
==
'\0'
)
{
path
=
DRIVE_GetDosCwd
(
drive
);
if
(
!
path
)
{
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
FALSE
;
}
}
else
if
(
path
[
0
]
==
'\\'
)
path
++
;
if
(
path
[
0
])
/* oops, we are in a subdir */
{
SetLastError
(
ERROR_INVALID_NAME
);
return
FALSE
;
}
}
else
{
if
(
!
root
[
0
])
SetLastError
(
ERROR_PATH_NOT_FOUND
);
else
SetLastError
(
ERROR_INVALID_NAME
);
return
FALSE
;
}
if
(
!
DRIVE_GetFreeSpace
(
drive
,
&
size
,
&
available
))
return
FALSE
;
/* Cap the size and available at 2GB as per specs. */
if
((
size
.
u
.
HighPart
)
||
(
size
.
u
.
LowPart
>
0x7fffffff
))
{
size
.
u
.
HighPart
=
0
;
size
.
u
.
LowPart
=
0x7fffffff
;
}
if
((
available
.
u
.
HighPart
)
||
(
available
.
u
.
LowPart
>
0x7fffffff
))
{
available
.
u
.
HighPart
=
0
;
available
.
u
.
LowPart
=
0x7fffffff
;
}
sec_size
=
(
DRIVE_GetType
(
drive
)
==
DRIVE_CDROM
)
?
2048
:
512
;
size
.
u
.
LowPart
/=
sec_size
;
available
.
u
.
LowPart
/=
sec_size
;
/* FIXME: probably have to adjust those variables too for CDFS */
cluster_sec
=
1
;
while
(
cluster_sec
*
65536
<
size
.
u
.
LowPart
)
cluster_sec
*=
2
;
if
(
cluster_sectors
)
*
cluster_sectors
=
cluster_sec
;
if
(
sector_bytes
)
*
sector_bytes
=
sec_size
;
if
(
free_clusters
)
*
free_clusters
=
available
.
u
.
LowPart
/
cluster_sec
;
if
(
total_clusters
)
*
total_clusters
=
size
.
u
.
LowPart
/
cluster_sec
;
return
TRUE
;
}
/***********************************************************************
* GetDiskFreeSpaceA (KERNEL32.@)
*/
BOOL
WINAPI
GetDiskFreeSpaceA
(
LPCSTR
root
,
LPDWORD
cluster_sectors
,
LPDWORD
sector_bytes
,
LPDWORD
free_clusters
,
LPDWORD
total_clusters
)
{
UNICODE_STRING
rootW
;
BOOL
ret
=
FALSE
;
if
(
root
)
{
if
(
!
RtlCreateUnicodeStringFromAsciiz
(
&
rootW
,
root
))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
}
else
rootW
.
Buffer
=
NULL
;
ret
=
GetDiskFreeSpaceW
(
rootW
.
Buffer
,
cluster_sectors
,
sector_bytes
,
free_clusters
,
total_clusters
);
RtlFreeUnicodeString
(
&
rootW
);
return
ret
;
}
/***********************************************************************
* GetDiskFreeSpaceExW (KERNEL32.@)
*
* This function is used to acquire the size of the available and
* total space on a logical volume.
*
* RETURNS
*
* Zero on failure, nonzero upon success. Use GetLastError to obtain
* detailed error information.
*
*/
BOOL
WINAPI
GetDiskFreeSpaceExW
(
LPCWSTR
root
,
PULARGE_INTEGER
avail
,
PULARGE_INTEGER
total
,
PULARGE_INTEGER
totalfree
)
{
int
drive
;
ULARGE_INTEGER
size
,
available
;
if
(
!
root
)
drive
=
DRIVE_GetCurrentDrive
();
else
{
/* C: always works for GetDiskFreeSpaceEx */
if
((
root
[
1
])
&&
((
root
[
1
]
!=
':'
)
||
(
root
[
2
]
&&
root
[
2
]
!=
'\\'
)))
{
FIXME
(
"there are valid root names which are not supported yet
\n
"
);
/* ..like UNC names, for instance. */
WARN
(
"invalid root '%s'
\n
"
,
debugstr_w
(
root
));
return
FALSE
;
}
drive
=
toupperW
(
root
[
0
])
-
'A'
;
}
if
(
!
DRIVE_GetFreeSpace
(
drive
,
&
size
,
&
available
))
return
FALSE
;
if
(
total
)
{
total
->
u
.
HighPart
=
size
.
u
.
HighPart
;
total
->
u
.
LowPart
=
size
.
u
.
LowPart
;
}
if
(
totalfree
)
{
totalfree
->
u
.
HighPart
=
available
.
u
.
HighPart
;
totalfree
->
u
.
LowPart
=
available
.
u
.
LowPart
;
}
if
(
avail
)
{
if
(
FIXME_ON
(
dosfs
))
{
/* On Windows2000, we need to check the disk quota
allocated for the user owning the calling process. We
don't want to be more obtrusive than necessary with the
FIXME messages, so don't print the FIXME unless Wine is
actually masquerading as Windows2000. */
RTL_OSVERSIONINFOEXW
ovi
;
ovi
.
dwOSVersionInfoSize
=
sizeof
(
ovi
);
if
(
RtlGetVersion
(
&
ovi
))
{
if
(
ovi
.
dwPlatformId
==
VER_PLATFORM_WIN32_NT
&&
ovi
.
dwMajorVersion
>
4
)
FIXME
(
"no per-user quota support yet
\n
"
);
}
}
/* Quick hack, should eventually be fixed to work 100% with
Windows2000 (see comment above). */
avail
->
u
.
HighPart
=
available
.
u
.
HighPart
;
avail
->
u
.
LowPart
=
available
.
u
.
LowPart
;
}
return
TRUE
;
}
/***********************************************************************
* GetDiskFreeSpaceExA (KERNEL32.@)
*/
BOOL
WINAPI
GetDiskFreeSpaceExA
(
LPCSTR
root
,
PULARGE_INTEGER
avail
,
PULARGE_INTEGER
total
,
PULARGE_INTEGER
totalfree
)
{
UNICODE_STRING
rootW
;
BOOL
ret
;
if
(
root
)
RtlCreateUnicodeStringFromAsciiz
(
&
rootW
,
root
);
else
rootW
.
Buffer
=
NULL
;
ret
=
GetDiskFreeSpaceExW
(
rootW
.
Buffer
,
avail
,
total
,
totalfree
);
RtlFreeUnicodeString
(
&
rootW
);
return
ret
;
}
/***********************************************************************
* GetDriveTypeW (KERNEL32.@)
*
* Returns the type of the disk drive specified. If root is NULL the
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment