From 837bd7b6f5d7ce089270ec5b7a50be0b564adaae Mon Sep 17 00:00:00 2001 From: wrowe Date: Tue, 6 Nov 2007 06:33:46 +0000 Subject: Now in 1.3.0 a valid csize becomes very critical to enable us to run the lfs sparse file tests. Make this so on win32 where we have Win2k and later, at least by filename (since it's documented that CompressedFileSize ~= allocation of a sparse file, yet there is no way to know this by-handle.) git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@592304 13f79535-47bb-0310-9956-ffa450edef68 --- file_io/win32/filestat.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'file_io') diff --git a/file_io/win32/filestat.c b/file_io/win32/filestat.c index af93bb933..f00887654 100644 --- a/file_io/win32/filestat.c +++ b/file_io/win32/filestat.c @@ -188,7 +188,8 @@ static apr_status_t resolve_ident(apr_finfo_t *finfo, const char *fname, return rv; } -static void guess_protection_bits(apr_finfo_t *finfo) +static apr_status_t guess_protection_bits(apr_finfo_t *finfo, + apr_int32_t wanted) { /* Read, write execute for owner. In the Win9x environment, any * readable file is executable (well, not entirely 100% true, but @@ -205,6 +206,8 @@ static void guess_protection_bits(apr_finfo_t *finfo) | (finfo->protection << prot_scope_user); finfo->valid |= APR_FINFO_UPROT | APR_FINFO_GPROT | APR_FINFO_WPROT; + + return ((wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS); } apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile, @@ -215,8 +218,9 @@ apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile, apr_status_t rv; if (apr_os_level < APR_WIN_NT) - guess_protection_bits(finfo); - else if (wanted & (APR_FINFO_PROT | APR_FINFO_OWNER)) + return guess_protection_bits(finfo, wanted); + + if (wanted & (APR_FINFO_PROT | APR_FINFO_OWNER)) { /* On NT this request is incredibly expensive, but accurate. * Since the WinNT-only functions below are protected by the @@ -286,9 +290,42 @@ apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile, resolve_prot(finfo, wanted, dacl); } else if (wanted & APR_FINFO_PROT) - guess_protection_bits(finfo); + guess_protection_bits(finfo, wanted); } + if ((apr_os_level >= APR_WIN_2000) && (wanted & APR_FINFO_CSIZE) + && (finfo->filetype == APR_REG)) + { + DWORD sizelo, sizehi; + if (whatfile == MORE_OF_HANDLE) { + /* Not available for development and implementation under + * a reasonable license; if you review the licensing + * terms and conditions of; + * http://go.microsoft.com/fwlink/?linkid=84083 + * you probably understand why APR chooses not to implement. + */ + ; + } + else { + SetLastError(NO_ERROR); + if (whatfile == MORE_OF_WFSPEC) + sizelo = GetCompressedFileSizeW((apr_wchar_t*)ufile, &sizehi); + else if (whatfile == MORE_OF_FSPEC) + sizelo = GetCompressedFileSizeA((char*)ufile, &sizehi); + + if (sizelo != INVALID_FILE_SIZE || GetLastError() == NO_ERROR) { +#if APR_HAS_LARGE_FILES + finfo->csize = (apr_off_t)sizelo + | ((apr_off_t)sizehi << 32); +#else + finfo->csize = (apr_off_t)sizelo; + if (finfo->csize < 0 || sizehi) + finfo->csize = 0x7fffffff; +#endif + finfo->valid |= APR_FINFO_CSIZE; + } + } + } return ((wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS); } -- cgit v1.2.1