On Wed, 1 Oct 2003, Pavel Roskin wrote: > FIXME about GetCompressedFileSizeA was too annoying when running Cygwin > programs, so I implemented it. The code uses st_blocks when possible to > account for sparse files and falls back to st_size if st_blocks is missing > in struct stat. The code uses shift operations so that both systems with > 32-bit and 64-bit off_t will do their best to provide accurate results. Sorry, the previous patch contained unrelated parts. Corrected patch is attached. -- Regards, Pavel Roskin
--- configure.ac +++ configure.ac @@ -1327,6 +1327,9 @@ #include <getopt.h> #endif]) +dnl Check for stat.st_blocks +AC_STRUCT_ST_BLOCKS + dnl *** check for the need to define platform-specific symbols case $host_cpu in --- win32/newfns.c +++ win32/newfns.c @@ -33,6 +33,9 @@ at a later date. */ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif #define NONAMELESSUNION #define NONAMELESSSTRUCT @@ -41,22 +44,22 @@ at a later date. */ #include "winnls.h" #include "winerror.h" #include "wine/debug.h" +#include "file.h" WINE_DEFAULT_DEBUG_CHANNEL(win32); /****************************************************************************** * GetCompressedFileSizeA [KERNEL32.@] - * - * NOTES - * This should call the W function below */ DWORD WINAPI GetCompressedFileSizeA( LPCSTR lpFileName, LPDWORD lpFileSizeHigh) { - FIXME("(...): stub\n"); - return 0xffffffff; + WCHAR fileW[MAX_PATHNAME_LEN]; + + MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, fileW, MAX_PATHNAME_LEN); + return GetCompressedFileSizeW( fileW, lpFileSizeHigh ); } @@ -71,8 +74,27 @@ DWORD WINAPI GetCompressedFileSizeW( LPCWSTR lpFileName, /* [in] Pointer to name of file */ LPDWORD lpFileSizeHigh) /* [out] Receives high-order doubleword of size */ { - FIXME("(%s,%p): stub\n",debugstr_w(lpFileName),lpFileSizeHigh); - return 0xffffffff; + DOS_FULL_NAME full_name; + struct stat st; + DWORD low; + + TRACE("(%s,%p)\n",debugstr_w(lpFileName),lpFileSizeHigh); + if ((lpFileName == NULL) || + (!DOSFS_GetFullName( lpFileName, TRUE, &full_name )) || + (stat(full_name.long_name, &st) != 0)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0xffffffff; + } +#if HAVE_STRUCT_STAT_ST_BLOCKS + /* blocks are 512 bytes long */ + *lpFileSizeHigh = (st.st_blocks >> 23); + low = ((st.st_blocks << 9) & 0xffffffff); +#else + *lpFileSizeHigh = (st.st_size >> 32); + low = (st.st_size & 0xffffffff); +#endif + return low; }