kernel32: Reimplement GetLogicalDrives using Nt{Open, Query}DirectoryObject.

This commit is contained in:
Alexandre Goujon 2012-07-28 16:14:15 +02:00 committed by Alexandre Julliard
parent 7ef5661d54
commit 4d7f510bef
1 changed files with 26 additions and 18 deletions

View File

@ -1435,28 +1435,36 @@ DWORD WINAPI QueryDosDeviceA( LPCSTR devname, LPSTR target, DWORD bufsize )
*/ */
DWORD WINAPI GetLogicalDrives(void) DWORD WINAPI GetLogicalDrives(void)
{ {
const char *config_dir = wine_get_config_dir(); static const WCHAR dosdevW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
struct stat st; OBJECT_ATTRIBUTES attr;
char *buffer, *dev; UNICODE_STRING nt_name;
DWORD ret = 0; DWORD bitmask = 0;
int i; NTSTATUS status;
HANDLE handle;
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, strlen(config_dir) + sizeof("/dosdevices/a:") ))) 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)
{ {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); char data[1024];
return 0; DIRECTORY_BASIC_INFORMATION *info = (DIRECTORY_BASIC_INFORMATION *)data;
} ULONG ctx = 0, len;
strcpy( buffer, config_dir );
strcat( buffer, "/dosdevices/a:" );
dev = buffer + strlen(buffer) - 2;
for (i = 0; i < 26; i++) while (!NtQueryDirectoryObject( handle, info, sizeof(data), 1, 0, &ctx, &len ))
{ if(info->ObjectName.Length == 2*sizeof(WCHAR) && info->ObjectName.Buffer[1] == ':')
*dev = 'a' + i; bitmask |= 1 << (info->ObjectName.Buffer[0] - 'A');
if (!stat( buffer, &st )) ret |= (1 << i);
NtClose( handle );
} }
HeapFree( GetProcessHeap(), 0, buffer );
return ret; return bitmask;
} }