Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=17823 Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- There might be a better way of deriving a serial from a UUID, but by my understanding, Linux uses version 4 UUIDs, and taking the last 4 bytes is as random as it can be. I don't know about Mac.
For folders such as drive_c which are not separate host systems, this returns a serial with the high byte containing the DOS drive letter, and the other three bytes zero, so it would seem to be exactly as unique and stable as the volume GUID itself.
dlls/mountmgr.sys/device.c | 3 +++ dlls/ntdll/tests/file.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c index 8fb984579e3..f68ab4de9b4 100644 --- a/dlls/mountmgr.sys/device.c +++ b/dlls/mountmgr.sys/device.c @@ -1123,6 +1123,9 @@ static NTSTATUS set_volume_info( struct volume *volume, struct dos_drive *drive, } }
+ if (!volume->serial) + memcpy(&volume->serial, &volume->guid.Data4[4], sizeof(DWORD)); + if (!volume->mount) volume->mount = add_volume_mount_point( disk_device->dev_obj, &disk_device->name, &volume->guid ); if (drive && !drive->mount) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 7b833fc9e86..f2e4ff069fd 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -3874,7 +3874,7 @@ static void test_query_volume_information_file(void) io.Information);
todo_wine ok(ffvi->VolumeCreationTime.QuadPart != 0, "Missing VolumeCreationTime\n"); - todo_wine ok(ffvi->VolumeSerialNumber != 0, "Missing VolumeSerialNumber\n"); + ok(ffvi->VolumeSerialNumber != 0, "Missing VolumeSerialNumber\n"); ok(ffvi->SupportsObjects == 1,"expected 1, got %d\n", ffvi->SupportsObjects); ok(ffvi->VolumeLabelLength == lstrlenW(ffvi->VolumeLabel) * sizeof(WCHAR), "got %d\n", ffvi->VolumeLabelLength);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- My apologies for forgetting to move those functions upwards in the first place...
dlls/ntdll/file.c | 246 ++++++++++++++++++++++++---------------------- 1 file changed, 126 insertions(+), 120 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 1adc1e094ec..bd35e88dda7 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -2237,6 +2237,124 @@ static NTSTATUS server_get_file_info( HANDLE handle, IO_STATUS_BLOCK *io, void *
}
+/* Find a DOS device which can act as the root of "path". + * Similar to find_drive_root(), but returns -1 instead of crossing volumes. */ +static int find_dos_device( const char *path ) +{ + int len = strlen(path); + int drive; + char *buffer; + struct stat st; + struct drive_info info[MAX_DOS_DRIVES]; + dev_t dev_id; + + if (!DIR_get_drives_info( info )) return -1; + + if (stat( path, &st ) < 0) return -1; + dev_id = st.st_dev; + + /* strip off trailing slashes */ + while (len > 1 && path[len - 1] == '/') len--; + + /* make a copy of the path */ + if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0, len + 1 ))) return -1; + memcpy( buffer, path, len ); + buffer[len] = 0; + + for (;;) + { + if (!stat( buffer, &st ) && S_ISDIR( st.st_mode )) + { + if (st.st_dev != dev_id) break; + + for (drive = 0; drive < MAX_DOS_DRIVES; drive++) + { + if ((info[drive].dev == st.st_dev) && (info[drive].ino == st.st_ino)) + { + if (len == 1) len = 0; /* preserve root slash in returned path */ + TRACE( "%s -> drive %c:, root=%s, name=%s\n", + debugstr_a(path), 'A' + drive, debugstr_a(buffer), debugstr_a(path + len)); + RtlFreeHeap( GetProcessHeap(), 0, buffer ); + return drive; + } + } + } + if (len <= 1) break; /* reached root */ + while (path[len - 1] != '/') len--; + while (path[len - 1] == '/') len--; + buffer[len] = 0; + } + RtlFreeHeap( GetProcessHeap(), 0, buffer ); + return -1; +} + +static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd ) +{ + struct mountmgr_unix_drive *drive; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING string; + ANSI_STRING unix_name; + IO_STATUS_BLOCK io; + HANDLE mountmgr; + NTSTATUS status; + int letter; + + if (server_get_unix_name( handle, &unix_name )) + return NULL; + + letter = find_dos_device( unix_name.Buffer ); + RtlFreeAnsiString( &unix_name ); + + if (!(drive = RtlAllocateHeap( GetProcessHeap(), 0, 1024 ))) + return NULL; + + if (letter == -1) + { + struct stat st; + + if (fstat( fd, &st ) == -1) + { + RtlFreeHeap( GetProcessHeap(), 0, drive ); + return NULL; + } + + drive->unix_dev = st.st_dev; + drive->letter = 0; + } + else + drive->letter = 'a' + letter; + + RtlInitUnicodeString( &string, MOUNTMGR_DEVICE_NAME ); + InitializeObjectAttributes( &attr, &string, 0, NULL, NULL ); + if (NtOpenFile( &mountmgr, GENERIC_READ | SYNCHRONIZE, &attr, &io, + FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT )) + return NULL; + + status = NtDeviceIoControlFile( mountmgr, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, + drive, sizeof(*drive), drive, 1024 ); + if (status == STATUS_BUFFER_OVERFLOW) + { + if (!(drive = RtlReAllocateHeap( GetProcessHeap(), 0, drive, drive->size ))) + { + RtlFreeHeap( GetProcessHeap(), 0, drive ); + NtClose( mountmgr ); + return NULL; + } + status = NtDeviceIoControlFile( mountmgr, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, + drive, sizeof(*drive), drive, drive->size ); + } + NtClose( mountmgr ); + + if (status) + { + WARN("failed to retrieve filesystem type from mountmgr, status %#x\n", status); + RtlFreeHeap( GetProcessHeap(), 0, drive ); + return NULL; + } + + return drive; +} + /****************************************************************************** * NtQueryInformationFile [NTDLL.@] * ZwQueryInformationFile [NTDLL.@] @@ -2507,8 +2625,15 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus(); else { + struct mountmgr_unix_drive *drive; FILE_ID_INFORMATION *info = ptr; - info->VolumeSerialNumber = 0; /* FIXME */ + + info->VolumeSerialNumber = 0; + if ((drive = get_mountmgr_fs_info( hFile, fd ))) + { + info->VolumeSerialNumber = drive->serial; + RtlFreeHeap( GetProcessHeap(), 0, drive ); + } memset( &info->FileId, 0, sizeof(info->FileId) ); *(ULONGLONG *)&info->FileId = st.st_ino; } @@ -3120,125 +3245,6 @@ static NTSTATUS get_device_info( int fd, FILE_FS_DEVICE_INFORMATION *info ) return STATUS_SUCCESS; }
-/* Find a DOS device which can act as the root of "path". - * Similar to find_drive_root(), but returns -1 instead of crossing volumes. */ -static int find_dos_device( const char *path ) -{ - int len = strlen(path); - int drive; - char *buffer; - struct stat st; - struct drive_info info[MAX_DOS_DRIVES]; - dev_t dev_id; - - if (!DIR_get_drives_info( info )) return -1; - - if (stat( path, &st ) < 0) return -1; - dev_id = st.st_dev; - - /* strip off trailing slashes */ - while (len > 1 && path[len - 1] == '/') len--; - - /* make a copy of the path */ - if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0, len + 1 ))) return -1; - memcpy( buffer, path, len ); - buffer[len] = 0; - - for (;;) - { - if (!stat( buffer, &st ) && S_ISDIR( st.st_mode )) - { - if (st.st_dev != dev_id) break; - - for (drive = 0; drive < MAX_DOS_DRIVES; drive++) - { - if ((info[drive].dev == st.st_dev) && (info[drive].ino == st.st_ino)) - { - if (len == 1) len = 0; /* preserve root slash in returned path */ - TRACE( "%s -> drive %c:, root=%s, name=%s\n", - debugstr_a(path), 'A' + drive, debugstr_a(buffer), debugstr_a(path + len)); - RtlFreeHeap( GetProcessHeap(), 0, buffer ); - return drive; - } - } - } - if (len <= 1) break; /* reached root */ - while (path[len - 1] != '/') len--; - while (path[len - 1] == '/') len--; - buffer[len] = 0; - } - RtlFreeHeap( GetProcessHeap(), 0, buffer ); - return -1; -} - -static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd ) -{ - struct mountmgr_unix_drive *drive; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING string; - ANSI_STRING unix_name; - IO_STATUS_BLOCK io; - HANDLE mountmgr; - NTSTATUS status; - int letter; - - if (server_get_unix_name( handle, &unix_name )) - return NULL; - - letter = find_dos_device( unix_name.Buffer ); - RtlFreeAnsiString( &unix_name ); - - if (!(drive = RtlAllocateHeap( GetProcessHeap(), 0, 1024 ))) - return NULL; - - if (letter == -1) - { - struct stat st; - - if (fstat( fd, &st ) == -1) - { - RtlFreeHeap( GetProcessHeap(), 0, drive ); - return NULL; - } - - drive->unix_dev = st.st_dev; - drive->letter = 0; - } - else - drive->letter = 'a' + letter; - - RtlInitUnicodeString( &string, MOUNTMGR_DEVICE_NAME ); - InitializeObjectAttributes( &attr, &string, 0, NULL, NULL ); - if (NtOpenFile( &mountmgr, GENERIC_READ | SYNCHRONIZE, &attr, &io, - FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT )) - return NULL; - - status = NtDeviceIoControlFile( mountmgr, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, - drive, sizeof(*drive), drive, 1024 ); - if (status == STATUS_BUFFER_OVERFLOW) - { - if (!(drive = RtlReAllocateHeap( GetProcessHeap(), 0, drive, drive->size ))) - { - RtlFreeHeap( GetProcessHeap(), 0, drive ); - NtClose( mountmgr ); - return NULL; - } - status = NtDeviceIoControlFile( mountmgr, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, - drive, sizeof(*drive), drive, drive->size ); - } - NtClose( mountmgr ); - - if (status) - { - WARN("failed to retrieve filesystem type from mountmgr, status %#x\n", status); - RtlFreeHeap( GetProcessHeap(), 0, drive ); - return NULL; - } - - return drive; -} - - /****************************************************************************** * NtQueryVolumeInformationFile [NTDLL.@] * ZwQueryVolumeInformationFile [NTDLL.@]
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69059
Your paranoid android.
=== debiant (32 bit report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
=== debiant (32 bit Chinese:China report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
=== debiant (32 bit WoW report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
=== debiant (64 bit WoW report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernel32/path.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c index 31652d3164b..334fc25e873 100644 --- a/dlls/kernel32/path.c +++ b/dlls/kernel32/path.c @@ -257,21 +257,12 @@ DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath, DWORD shortlen
static BOOL is_same_file(HANDLE h1, HANDLE h2) { - int fd1; - BOOL ret = FALSE; - if (wine_server_handle_to_fd(h1, 0, &fd1, NULL) == STATUS_SUCCESS) - { - int fd2; - if (wine_server_handle_to_fd(h2, 0, &fd2, NULL) == STATUS_SUCCESS) - { - struct stat stat1, stat2; - if (fstat(fd1, &stat1) == 0 && fstat(fd2, &stat2) == 0) - ret = (stat1.st_dev == stat2.st_dev && stat1.st_ino == stat2.st_ino); - wine_server_release_fd(h2, fd2); - } - wine_server_release_fd(h1, fd1); - } - return ret; + FILE_ID_INFORMATION id1, id2; + IO_STATUS_BLOCK io; + + return !NtQueryInformationFile( h1, &io, &id1, sizeof(id1), FileIdInformation ) + && !NtQueryInformationFile( h2, &io, &id2, sizeof(id2), FileIdInformation ) + && !memcmp( &id1, &id2, sizeof(FILE_ID_INFORMATION) ); }
/**************************************************************************
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69060
Your paranoid android.
=== debiant (32 bit report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
=== debiant (32 bit Chinese:China report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
=== debiant (32 bit WoW report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
=== debiant (64 bit WoW report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
Signed-off-by: Zebediah Figura zfigura@codeweavers.com ---
This paves the way for an implementation of GetVolumeInformation() on top of ntdll. Unfortunately, I ran into a snag while doing so, which is that one of the tests attempts to open a file by a device path other than the DOS one (specifically, \?\Volume{...}). mountmgr allows that, which was enough for kernel32 to fall back to assuming NTFS. Unless we implement a similar fallback (which feels much like papering over the problem), that test would start failing.
I don't know how to resolve this. One way is to hook up the missing IRPs in mountmgr, but this seems like more work than its worth. It'd be nice for ntdll to be able to recognize volume paths such that they resolve to the same Unix file object as the equivalent DOS path, but there are many ways to achieve this goal and I can't even guess at what would be the right one.
dlls/kernel32/tests/volume.c | 68 ++++++++++++++++++++++++++++++++++++ dlls/kernel32/volume.c | 67 +++++++++++++++++++++++++++-------- 2 files changed, 120 insertions(+), 15 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 37d15fd3f8c..126df5b8a0f 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -60,6 +60,7 @@ static BOOL (WINAPI *pGetVolumePathNameA)(LPCSTR, LPSTR, DWORD); static BOOL (WINAPI *pGetVolumePathNamesForVolumeNameA)(LPCSTR, LPSTR, DWORD, LPDWORD); static BOOL (WINAPI *pGetVolumePathNamesForVolumeNameW)(LPCWSTR, LPWSTR, DWORD, LPDWORD); static BOOL (WINAPI *pCreateSymbolicLinkA)(const char *, const char *, DWORD); +static BOOL (WINAPI *pGetVolumeInformationByHandleW)(HANDLE, WCHAR *, DWORD, DWORD *, DWORD *, DWORD *, WCHAR *, DWORD);
/* ############################### */
@@ -1520,6 +1521,71 @@ static void test_mounted_folder(void) ok(ret, "got error %u\n", GetLastError()); }
+static void test_GetVolumeInformationByHandle(void) +{ + char buffer[50] DECLSPEC_ALIGN(8); + FILE_FS_ATTRIBUTE_INFORMATION *attr_info = (void *)buffer; + FILE_FS_VOLUME_INFORMATION *volume_info = (void *)buffer; + DWORD serial, filename_len, flags; + WCHAR label[20], fsname[20]; + IO_STATUS_BLOCK io; + HANDLE file; + NTSTATUS status; + BOOL ret; + + if (!pGetVolumeInformationByHandleW) + { + win_skip("GetVolumeInformationByHandleW is not present.\n"); + return; + } + + file = CreateFileA( "C:/windows", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL ); + ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = pGetVolumeInformationByHandleW( INVALID_HANDLE_VALUE, label, ARRAY_SIZE(label), &serial, + &filename_len, &flags, fsname, ARRAY_SIZE(fsname) ); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "got error %u\n", GetLastError()); + + ret = pGetVolumeInformationByHandleW( file, NULL, 0, NULL, NULL, NULL, NULL, 0 ); + ok(ret, "got error %u\n", GetLastError()); + + ret = pGetVolumeInformationByHandleW( file, label, ARRAY_SIZE(label), &serial, + &filename_len, &flags, fsname, ARRAY_SIZE(fsname) ); + ok(ret, "got error %u\n", GetLastError()); + + memset(buffer, 0, sizeof(buffer)); + status = NtQueryVolumeInformationFile( file, &io, buffer, sizeof(buffer), FileFsAttributeInformation ); + ok(!status, "got status %#x\n", status); + ok(flags == attr_info->FileSystemAttributes, "expected flags %#x, got %#x\n", + attr_info->FileSystemAttributes, flags); + ok(filename_len == attr_info->MaximumComponentNameLength, "expected filename_len %u, got %u\n", + attr_info->MaximumComponentNameLength, filename_len); + ok(!wcscmp( fsname, attr_info->FileSystemName ), "expected fsname %s, got %s\n", + debugstr_w( attr_info->FileSystemName ), debugstr_w( fsname )); + ok(wcslen( fsname ) == attr_info->FileSystemNameLength / sizeof(WCHAR), + "expected fsname length %u, got %u\n", attr_info->FileSystemNameLength / sizeof(WCHAR), wcslen( fsname )); + + SetLastError(0xdeadbeef); + ret = pGetVolumeInformationByHandleW( file, NULL, 0, NULL, &filename_len, &flags, fsname, 2 ); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_BAD_LENGTH, "got error %u\n", GetLastError()); + + memset(buffer, 0, sizeof(buffer)); + status = NtQueryVolumeInformationFile( file, &io, buffer, sizeof(buffer), FileFsVolumeInformation ); + ok(!status, "got status %#x\n", status); + ok(serial == volume_info->VolumeSerialNumber, "expected serial %08x, got %08x\n", + volume_info->VolumeSerialNumber, serial); + ok(!wcscmp( label, volume_info->VolumeLabel ), "expected label %s, got %s\n", + debugstr_w( volume_info->VolumeLabel ), debugstr_w( label )); + ok(wcslen( label ) == volume_info->VolumeLabelLength / sizeof(WCHAR), + "expected label length %u, got %u\n", volume_info->VolumeLabelLength / sizeof(WCHAR), wcslen( label )); + + CloseHandle( file ); +} + START_TEST(volume) { hdll = GetModuleHandleA("kernel32.dll"); @@ -1535,6 +1601,7 @@ START_TEST(volume) pGetVolumePathNamesForVolumeNameA = (void *) GetProcAddress(hdll, "GetVolumePathNamesForVolumeNameA"); pGetVolumePathNamesForVolumeNameW = (void *) GetProcAddress(hdll, "GetVolumePathNamesForVolumeNameW"); pCreateSymbolicLinkA = (void *) GetProcAddress(hdll, "CreateSymbolicLinkA"); + pGetVolumeInformationByHandleW = (void *) GetProcAddress(hdll, "GetVolumeInformationByHandleW");
test_query_dos_deviceA(); test_dos_devices(); @@ -1553,4 +1620,5 @@ START_TEST(volume) test_GetVolumePathNamesForVolumeNameW(); test_cdrom_ioctl(); test_mounted_folder(); + test_GetVolumeInformationByHandle(); } diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c index 4f0f4a0a0fc..7555dd9e95d 100644 --- a/dlls/kernel32/volume.c +++ b/dlls/kernel32/volume.c @@ -2117,21 +2117,58 @@ BOOL WINAPI SetVolumeMountPointW(LPCWSTR path, LPCWSTR volume) /*********************************************************************** * GetVolumeInformationByHandleW (KERNEL32.@) */ -BOOL WINAPI GetVolumeInformationByHandleW(HANDLE handle, WCHAR *volnamebuf, DWORD volnamesize, DWORD *volserial, DWORD *maxlength, DWORD *flags, WCHAR *fsnamebuf, DWORD fsnamesize) +BOOL WINAPI GetVolumeInformationByHandleW( HANDLE handle, WCHAR *label, DWORD label_len, + DWORD *serial, DWORD *filename_len, DWORD *flags, + WCHAR *fsname, DWORD fsname_len ) { - FIXME("%p %p %d %p %p %p %p %d\n", handle, volnamebuf, volnamesize, volserial, maxlength, flags, fsnamebuf, fsnamesize); - - if(volnamebuf && volnamesize) - *volnamebuf = 0; - if(volserial) - *volserial = 0; - if(maxlength) - *maxlength = 0; - if(flags) - *flags = 0; - if(fsnamebuf && fsnamesize) - *fsnamebuf = 0; + IO_STATUS_BLOCK io;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + TRACE( "%p\n", handle ); + + if (label || serial) + { + char buffer[sizeof(FILE_FS_VOLUME_INFORMATION) + MAX_PATH * sizeof(WCHAR)]; + FILE_FS_VOLUME_INFORMATION *info = (FILE_FS_VOLUME_INFORMATION *)buffer; + + if (!set_ntstatus( NtQueryVolumeInformationFile( handle, &io, info, sizeof(buffer), + FileFsVolumeInformation ) )) + return FALSE; + + if (label) + { + if (label_len < info->VolumeLabelLength / sizeof(WCHAR) + 1) + { + SetLastError( ERROR_BAD_LENGTH ); + return FALSE; + } + memcpy( label, info->VolumeLabel, info->VolumeLabelLength ); + label[info->VolumeLabelLength / sizeof(WCHAR)] = 0; + } + if (serial) *serial = info->VolumeSerialNumber; + } + + if (filename_len || flags || fsname) + { + char buffer[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + MAX_PATH * sizeof(WCHAR)]; + FILE_FS_ATTRIBUTE_INFORMATION *info = (FILE_FS_ATTRIBUTE_INFORMATION *)buffer; + + if (!set_ntstatus( NtQueryVolumeInformationFile( handle, &io, info, sizeof(buffer), + FileFsAttributeInformation ) )) + return FALSE; + + if (fsname) + { + if (fsname_len < info->FileSystemNameLength / sizeof(WCHAR) + 1) + { + SetLastError( ERROR_BAD_LENGTH ); + return FALSE; + } + memcpy( fsname, info->FileSystemName, info->FileSystemNameLength ); + fsname[info->FileSystemNameLength / sizeof(WCHAR)] = 0; + } + if (filename_len) *filename_len = info->MaximumComponentNameLength; + if (flags) *flags = info->FileSystemAttributes; + } + + return TRUE; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69061
Your paranoid android.
=== debiant (32 bit report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
=== debiant (32 bit Chinese:China report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
=== debiant (32 bit WoW report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000
=== debiant (64 bit WoW report) ===
ntdll: file.c:3694: Test failed: expected 00000000, got 43000000