On Wednesday, April 23 2014, "Corinna Vinschen" wrote to "cygwin at cygwin.com" saying:
> Rather than calling GetFileInformationByHandle, try this > > #include <winternl.h> > > [...] > > NTSTATUS status; > IO_STATUS_BLOCK io; > FILE_NETWORK_OPEN_INFORMATION fnoi; > > status = NtQueryInformationFile (file, &io, &fnoi, sizeof fnoi, > FileNetworkOpenInformation); > if (!NT_SUCCESS (status)) > { > fprintf (stderr, "NtQueryInformationFile: 0x%08x\n", status); > [...] > } > printf("%s: NtQueryInformationFile: nFileSize=%" PRIu64 "\n", > argv[i], fnoi.EndOfFile.QuadPart); > > Maybe that's really the problem. If so, either the EndOfFile info > is wrong, or (more likely) the call to NtQueryInformationFile returns > with a non-0 status code, which would be interesting to know. It's > probably not STATUS_INVALID_PARAMETER, otherwise you probably wouldn't > have seen a problem at all. > > Replacing the above call with > > FILE_STANDARD_INFORMATION fsi; > status = NtQueryInformationFile (file, &io, &fsi, sizeof fsi, > FileStandardInformation); > [...] > printf("%s: NtQueryInformationFile: nFileSize=%" PRIu64 "\n", > argv[i], fsi.EndOfFile.QuadPart); > > should then give the correct result. Okay, looks like FileNetworkOpenInformation is succeeding, but returning a bad EndOfFile value. $ ./win32-size-test 'z:\foo' z:\foo: NtQueryInformationFile(FileNetworkOpenInformation): EndOfFile=0 z:\foo: NtQueryInformationFile(FileStandardInformation): EndOfFile=12 $ gdb --quiet --args ./win32-size-test.exe 'z:\foo' Reading symbols from /cygdrive/z/Emacs-Modtime/win32-size-test.exe...done. (gdb) break 82 Breakpoint 1 at 0x100401400: file win32-size-test.c, line 82. (gdb) run Starting program: /cygdrive/z/Emacs-Modtime/win32-size-test.exe z:\\foo [New Thread 10540.0x48dc] [New Thread 10540.0x39d4] z:\\foo: NtQueryInformationFile(FileNetworkOpenInformation): EndOfFile=0 z:\\foo: NtQueryInformationFile(FileStandardInformation): EndOfFile=12 Breakpoint 1, main (argc=2, argv=0x22aaf0) at win32-size-test.c:82 82 if (!CloseHandle(file)) { (gdb) p fnoi $1 = {CreationTime = {{LowPart = 1493948928, HighPart = 30367507}, u = { LowPart = 1493948928, HighPart = 30367507}, QuadPart = 130427450920000000}, LastAccessTime = {{LowPart = 1493948928, HighPart = 30367507}, u = {LowPart = 1493948928, HighPart = 30367507}, QuadPart = 130427450920000000}, LastWriteTime = {{LowPart = 1493948928, HighPart = 30367507}, u = {LowPart = 1493948928, HighPart = 30367507}, QuadPart = 130427450920000000}, ChangeTime = {{LowPart = 1493948928, HighPart = 30367507}, u = {LowPart = 1493948928, HighPart = 30367507}, QuadPart = 130427450920000000}, AllocationSize = {{LowPart = 12, HighPart = 0}, u = {LowPart = 12, HighPart = 0}, QuadPart = 12}, EndOfFile = {{LowPart = 0, HighPart = 0}, u = {LowPart = 0, HighPart = 0}, QuadPart = 0}, FileAttributes = 128} (gdb) p fsi $2 = {AllocationSize = {{LowPart = 12, HighPart = 0}, u = {LowPart = 12, HighPart = 0}, QuadPart = 12}, EndOfFile = {{LowPart = 12, HighPart = 0}, u = {LowPart = 12, HighPart = 0}, QuadPart = 12}, NumberOfLinks = 1, DeletePending = 0 '\000', Directory = 0 '\000'} At this point this is looking pretty clearly like a Parallels Tools bug. I'll report it to them. > Also, to add handling for the Parallels filesystem to Cygwin, I'd > need the info printed by the getVolInfo tool from the csih package: > > $ /usr/lib/csih/getVolInfo /cygdrive/z $ /usr/lib/csih/getVolInfo.exe /cygdrive/z/ Device Type : 7 Characteristics : 10 Volume Name : <Shared Folders> Serial Number : 0 Max Filenamelength : 255 Filesystemname : <PrlSF> Flags : 3 FILE_CASE_SENSITIVE_SEARCH : TRUE FILE_CASE_PRESERVED_NAMES : TRUE FILE_UNICODE_ON_DISK : FALSE FILE_PERSISTENT_ACLS : FALSE FILE_FILE_COMPRESSION : FALSE FILE_VOLUME_QUOTAS : FALSE FILE_SUPPORTS_SPARSE_FILES : FALSE FILE_SUPPORTS_REPARSE_POINTS: FALSE FILE_SUPPORTS_REMOTE_STORAGE: FALSE FILE_VOLUME_IS_COMPRESSED : FALSE FILE_SUPPORTS_OBJECT_IDS : FALSE FILE_SUPPORTS_ENCRYPTION : FALSE FILE_NAMED_STREAMS : FALSE FILE_READ_ONLY_VOLUME : FALSE FILE_SEQUENTIAL_WRITE_ONCE : FALSE FILE_SUPPORTS_TRANSACTIONS : FALSE Here's my test code. Compiles with either Cygwin or mingw64 GCC, but not classic mingw or Visual Studio due to missing headers/declarations. Link with -lntdll.
#include <windows.h> #include <stdio.h> #include <inttypes.h> #include <winternl.h> #if __LP64__ #define PRIuDWORD "u" #define PRIxDWORD "x" #else #define PRIuDWORD "lu" #define PRIxDWORD "lx" #endif static const char* geterr(DWORD err) { static char msg[1024]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)msg, sizeof(msg), NULL); return msg; } int main(int argc, char* argv[]) { int i; int exitstatus = 0; for (i = 1; i < argc; i++) { HANDLE file; DWORD err, bytesWritten; NTSTATUS ntstatus; IO_STATUS_BLOCK io; FILE_NETWORK_OPEN_INFORMATION fnoi; FILE_STANDARD_INFORMATION fsi; file = CreateFileA(argv[i], GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) { err = GetLastError(); fprintf(stderr, "%s: CreateFile: %s (err 0x%08" PRIxDWORD")\n", argv[i], geterr(err), err); exitstatus++; continue; } if (!WriteFile(file, "Hello world!\n", 12, &bytesWritten, NULL) || bytesWritten != 12) { err = GetLastError(); fprintf(stderr, "%s: WriteFile: %s (err 0x%08" PRIxDWORD ")\n", argv[i], geterr(err), err); CloseHandle(file); exitstatus++; continue; } ntstatus = NtQueryInformationFile (file, &io, &fnoi, sizeof fnoi, FileNetworkOpenInformation); if (!NT_SUCCESS (ntstatus)) { fprintf (stderr, "%s: NtQueryInformationFile(FileNetworkOpenInformation): %s (err 0x%08" PRIxDWORD ")\n", argv[i], geterr(ntstatus), ntstatus); } else { printf("%s: NtQueryInformationFile(FileNetworkOpenInformation): EndOfFile=%" PRIu64 "\n", argv[i], (uint64_t)fnoi.EndOfFile.QuadPart); } ntstatus = NtQueryInformationFile (file, &io, &fsi, sizeof fsi, FileStandardInformation); if (!NT_SUCCESS (ntstatus)) { fprintf (stderr, "%s: NtQueryInformationFile(FileStandardInformation): %s (err 0x%08" PRIxDWORD ")\n", argv[i], geterr(ntstatus), ntstatus); } else { printf("%s: NtQueryInformationFile(FileStandardInformation): EndOfFile=%" PRIu64 "\n", argv[i], (uint64_t)fsi.EndOfFile.QuadPart); } if (!CloseHandle(file)) { err = GetLastError(); fprintf(stderr, "%s: CloseHandle: %s (err %" PRIxDWORD ")\n", argv[i], geterr(err), err); exitstatus++; continue; } } return exitstatus; }
-- Jonathan Lennox lennox at cs.columbia.edu
-- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple