Alexandre Julliard : kernel32: Fetch more information from the DosDevices directory for QueryDosDevice.
Alexandre Julliard
julliard at winehq.org
Fri Jul 24 08:49:14 CDT 2009
Module: wine
Branch: master
Commit: f18276fe0bc0bedf5c58c51f53f9491265f500dc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f18276fe0bc0bedf5c58c51f53f9491265f500dc
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Jul 24 11:01:41 2009 +0200
kernel32: Fetch more information from the DosDevices directory for QueryDosDevice.
---
dlls/kernel32/volume.c | 66 ++++++++++++++++++++++++++++-------------------
1 files changed, 39 insertions(+), 27 deletions(-)
diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c
index 0f4161c..9fcd061 100644
--- a/dlls/kernel32/volume.c
+++ b/dlls/kernel32/volume.c
@@ -1018,11 +1018,10 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
static const WCHAR prnW[] = {'P','R','N',0};
static const WCHAR comW[] = {'C','O','M',0};
static const WCHAR lptW[] = {'L','P','T',0};
- static const WCHAR rootW[] = {'A',':','\\',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 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};
+ static const WCHAR dosdevW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
UNICODE_STRING nt_name;
ANSI_STRING unix_name;
@@ -1046,15 +1045,21 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
memcpy( name, devname + HIWORD(dosdev)/sizeof(WCHAR), LOWORD(dosdev) );
name[LOWORD(dosdev)/sizeof(WCHAR)] = 0;
}
- else if (devname[0] && devname[1] == ':' && !devname[2])
+ else
{
- /* FIXME: should do this for all devices, not just drives */
NTSTATUS status;
- WCHAR buffer[sizeof(driveW)/sizeof(WCHAR)];
+ WCHAR *buffer;
- memcpy( buffer, driveW, sizeof(driveW) );
- buffer[12] = devname[0];
- if ((status = read_nt_symlink( buffer, target, bufsize )))
+ if (!(buffer = HeapAlloc( GetProcessHeap(), 0, sizeof(dosdevW) + strlenW(devname)*sizeof(WCHAR) )))
+ {
+ SetLastError( ERROR_OUTOFMEMORY );
+ return 0;
+ }
+ memcpy( buffer, dosdevW, sizeof(dosdevW) );
+ strcatW( buffer, devname );
+ status = read_nt_symlink( buffer, target, bufsize );
+ HeapFree( GetProcessHeap(), 0, buffer );
+ if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return 0;
@@ -1062,11 +1067,8 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
ret = strlenW( target ) + 1;
goto done;
}
- else
- {
- SetLastError( ERROR_BAD_PATHNAME );
- return 0;
- }
+
+ /* FIXME: should read NT symlink for all devices */
if (!(path = get_dos_device_path( name ))) return 0;
link = read_symlink( path );
@@ -1125,6 +1127,8 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
}
else /* return a list of all devices */
{
+ OBJECT_ATTRIBUTES attr;
+ HANDLE handle;
WCHAR *p = target;
int i;
@@ -1134,6 +1138,8 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
return 0;
}
+ /* FIXME: these should be NT symlinks too */
+
memcpy( p, auxW, sizeof(auxW) );
p += sizeof(auxW) / sizeof(WCHAR);
memcpy( p, nulW, sizeof(nulW) );
@@ -1180,30 +1186,36 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
}
}
- strcpyW( nt_buffer + 4, rootW );
- RtlInitUnicodeString( &nt_name, nt_buffer );
-
- /* FIXME: should simply enumerate the DosDevices directory instead */
- for (i = 0; i < 26; i++)
+ RtlInitUnicodeString( &nt_name, dosdevW );
+ nt_name.Length -= sizeof(WCHAR); /* without trailing slash */
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &nt_name;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+ status = NtOpenDirectoryObject( &handle, FILE_LIST_DIRECTORY, &attr );
+ if (!status)
{
- WCHAR buffer[sizeof(driveW)/sizeof(WCHAR)], dummy[8];
- NTSTATUS status;
+ char data[1024];
+ DIRECTORY_BASIC_INFORMATION *info = (DIRECTORY_BASIC_INFORMATION *)data;
+ ULONG ctx = 0, len;
- 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)
+ while (!NtQueryDirectoryObject( handle, info, sizeof(data), 1, 0, &ctx, &len ))
{
- if (p + 3 >= target + bufsize)
+ if (p + info->ObjectName.Length/sizeof(WCHAR) + 1 >= target + bufsize)
{
SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ NtClose( handle );
return 0;
}
- *p++ = 'A' + i;
- *p++ = ':';
+ memcpy( p, info->ObjectName.Buffer, info->ObjectName.Length );
+ p += info->ObjectName.Length/sizeof(WCHAR);
*p++ = 0;
}
+ NtClose( handle );
}
+
*p++ = 0; /* terminating null */
return p - target;
}
More information about the wine-cvs
mailing list