public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: lennox@cs.columbia.edu
To: cygwin@cygwin.com
Subject: Re: fstat st_size on open files on Parallels filesystem is wrong
Date: Wed, 23 Apr 2014 16:47:00 -0000	[thread overview]
Message-ID: <21335.61113.963950.516021@compute01.cs.columbia.edu> (raw)
In-Reply-To: <20140423084056.GJ2339@calimero.vinschen.de>

[-- Attachment #1: message body text --]
[-- Type: text/plain, Size: 4633 bytes --]

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.


[-- Attachment #2: win32-size-test.c --]
[-- Type: text/plain, Size: 2409 bytes --]

#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;
}

[-- Attachment #3: .signature --]
[-- Type: text/plain, Size: 49 bytes --]



-- 
Jonathan Lennox
lennox at cs.columbia.edu


[-- Attachment #4: Type: text/plain, Size: 218 bytes --]

--
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

  reply	other threads:[~2014-04-23 16:47 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-21 18:27 lennox
2014-04-21 18:35 ` Andrey Repin
2014-04-21 18:46   ` lennox
2014-04-22  8:16     ` Corinna Vinschen
2014-04-22 16:09       ` lennox
2014-04-22 20:57       ` lennox
2014-04-23  8:41         ` Corinna Vinschen
2014-04-23 16:47           ` lennox [this message]
2014-04-23 17:24             ` Corinna Vinschen
2015-10-08 16:16               ` Jonathan Lennox
2015-10-21 11:07                 ` Corinna Vinschen
2015-11-02  9:38                   ` Jonathan Lennox
2015-11-02 11:23                     ` Corinna Vinschen
2015-11-02 13:08                       ` Jonathan Lennox
2015-11-02 14:06                         ` Corinna Vinschen
2015-11-02 22:05                           ` Jonathan Lennox
2015-11-03 12:19                             ` Corinna Vinschen
2015-11-04  6:35                               ` Jonathan Lennox
2015-11-04  9:45                                 ` Corinna Vinschen
2015-11-02 12:52                     ` cyg Simple

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=21335.61113.963950.516021@compute01.cs.columbia.edu \
    --to=lennox@cs.columbia.edu \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).