Commit 6dee4c6e authored by Alexandre Julliard's avatar Alexandre Julliard

kernel32: Return the Windows symlink in QueryDosDevice instead of the Unix one.

parent cb566755
...@@ -51,7 +51,7 @@ static void test_query_dos_deviceA(void) ...@@ -51,7 +51,7 @@ static void test_query_dos_deviceA(void)
if (strstr(buffer, "HARDDISK") || strstr(buffer, "RAMDISK")) found = TRUE; if (strstr(buffer, "HARDDISK") || strstr(buffer, "RAMDISK")) found = TRUE;
} }
} }
todo_wine ok(found, "expected at least one devicename to contain HARDDISK or RAMDISK\n"); ok(found, "expected at least one devicename to contain HARDDISK or RAMDISK\n");
} }
static void test_FindFirstVolume(void) static void test_FindFirstVolume(void)
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(volume); WINE_DEFAULT_DEBUG_CHANNEL(volume);
#define SUPERBLOCK_SIZE 2048 #define SUPERBLOCK_SIZE 2048
#define SYMBOLIC_LINK_QUERY 0x0001
#define CDFRAMES_PERSEC 75 #define CDFRAMES_PERSEC 75
#define CDFRAMES_PERMIN (CDFRAMES_PERSEC * 60) #define CDFRAMES_PERMIN (CDFRAMES_PERSEC * 60)
...@@ -128,6 +129,33 @@ static char *get_dos_device_path( LPCWSTR name ) ...@@ -128,6 +129,33 @@ static char *get_dos_device_path( LPCWSTR name )
return buffer; return buffer;
} }
/* read the contents of an NT symlink object */
static NTSTATUS read_nt_symlink( const WCHAR *name, WCHAR *target, DWORD size )
{
NTSTATUS status;
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW;
HANDLE handle;
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.ObjectName = &nameW;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
RtlInitUnicodeString( &nameW, name );
if (!(status = NtOpenSymbolicLinkObject( &handle, SYMBOLIC_LINK_QUERY, &attr )))
{
UNICODE_STRING targetW;
targetW.Buffer = target;
targetW.MaximumLength = (size - 1) * sizeof(WCHAR);
status = NtQuerySymbolicLinkObject( handle, &targetW, NULL );
if (!status) target[targetW.Length / sizeof(WCHAR)] = 0;
NtClose( handle );
}
return status;
}
/* open a handle to a device root */ /* open a handle to a device root */
static BOOL open_device_root( LPCWSTR root, HANDLE *handle ) static BOOL open_device_root( LPCWSTR root, HANDLE *handle )
...@@ -916,6 +944,7 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize ) ...@@ -916,6 +944,7 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
static const WCHAR com0W[] = {'\\','?','?','\\','C','O','M','0',0}; static const WCHAR com0W[] = {'\\','?','?','\\','C','O','M','0',0};
static const WCHAR com1W[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','C','O','M','1',0,0}; static const WCHAR com1W[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','C','O','M','1',0,0};
static const WCHAR lpt1W[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','L','P','T','1',0,0}; static const WCHAR lpt1W[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','L','P','T','1',0,0};
static const WCHAR driveW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','A',':',0};
UNICODE_STRING nt_name; UNICODE_STRING nt_name;
ANSI_STRING unix_name; ANSI_STRING unix_name;
...@@ -941,7 +970,19 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize ) ...@@ -941,7 +970,19 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
} }
else if (devname[0] && devname[1] == ':' && !devname[2]) else if (devname[0] && devname[1] == ':' && !devname[2])
{ {
memcpy( name, devname, 3 * sizeof(WCHAR) ); /* FIXME: should do this for all devices, not just drives */
NTSTATUS status;
WCHAR buffer[sizeof(driveW)/sizeof(WCHAR)];
memcpy( buffer, driveW, sizeof(driveW) );
buffer[12] = devname[0];
if ((status = read_nt_symlink( buffer, target, bufsize )))
{
SetLastError( RtlNtStatusToDosError(status) );
return 0;
}
ret = strlenW( target ) + 1;
goto done;
} }
else else
{ {
...@@ -995,7 +1036,7 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize ) ...@@ -995,7 +1036,7 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
RtlFreeAnsiString( &unix_name ); RtlFreeAnsiString( &unix_name );
} }
} }
done:
if (ret) if (ret)
{ {
if (ret < bufsize) target[ret++] = 0; /* add an extra null */ if (ret < bufsize) target[ret++] = 0; /* add an extra null */
...@@ -1064,12 +1105,17 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize ) ...@@ -1064,12 +1105,17 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
strcpyW( nt_buffer + 4, rootW ); strcpyW( nt_buffer + 4, rootW );
RtlInitUnicodeString( &nt_name, nt_buffer ); RtlInitUnicodeString( &nt_name, nt_buffer );
/* FIXME: should simply enumerate the DosDevices directory instead */
for (i = 0; i < 26; i++) for (i = 0; i < 26; i++)
{ {
nt_buffer[4] = 'a' + i; WCHAR buffer[sizeof(driveW)/sizeof(WCHAR)], dummy[8];
if (!wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, TRUE )) NTSTATUS status;
memcpy( buffer, driveW, sizeof(driveW) );
buffer[12] = 'A' + i;
status = read_nt_symlink( buffer, dummy, sizeof(dummy)/sizeof(WCHAR) );
if (status == STATUS_SUCCESS || status == STATUS_BUFFER_TOO_SMALL)
{ {
RtlFreeAnsiString( &unix_name );
if (p + 3 >= target + bufsize) if (p + 3 >= target + bufsize)
{ {
SetLastError( ERROR_INSUFFICIENT_BUFFER ); SetLastError( ERROR_INSUFFICIENT_BUFFER );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment