* autoload.cc (NetUseGetInfo): Define.

* fhandler_disk_file.cc (fhandler_cygdrive::opendir): Rename flptst
	to drive.  Call new get_disk_type function rather than is_floppy and
	check SMB drives with the NetUseGetInfo function.  Explain why.
	* mount.cc (get_disk_type): New function to evaluate disk type from
	native NT device name.
	(is_floppy): Remove.
	* mount.h (enum disk_type): Define.
	(get_disk_type): Declare.
	* path.h (is_floppy): Drop declaration.
This commit is contained in:
Corinna Vinschen 2012-02-16 11:02:05 +00:00
parent fb97e87479
commit 9de0461985
6 changed files with 91 additions and 13 deletions

View File

@ -1,3 +1,16 @@
2012-02-16 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (NetUseGetInfo): Define.
* fhandler_disk_file.cc (fhandler_cygdrive::opendir): Rename flptst
to drive. Call new get_disk_type function rather than is_floppy and
check SMB drives with the NetUseGetInfo function. Explain why.
* mount.cc (get_disk_type): New function to evaluate disk type from
native NT device name.
(is_floppy): Remove.
* mount.h (enum disk_type): Define.
(get_disk_type): Declare.
* path.h (is_floppy): Drop declaration.
2012-02-15 Corinna Vinschen <corinna@vinschen.de>
* miscfuncs.cc: Revert change from 2012-02-13 which used the

View File

@ -406,6 +406,7 @@ LoadDLLfunc (WNetOpenEnumA, 20, mpr)
LoadDLLfunc (DsGetDcNameW, 24, netapi32)
LoadDLLfunc (NetApiBufferFree, 4, netapi32)
LoadDLLfunc (NetUseGetInfo, 16, netapi32)
LoadDLLfunc (NetUserGetGroups, 28, netapi32)
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
LoadDLLfunc (NetUserGetLocalGroups, 32, netapi32)

View File

@ -25,6 +25,7 @@ details. */
#include "tls_pbuf.h"
#include "pwdgrp.h"
#include <winioctl.h>
#include <lm.h>
#define _COMPILING_NEWLIB
#include <dirent.h>
@ -2412,7 +2413,7 @@ fhandler_cygdrive::opendir (int fd)
int
fhandler_cygdrive::readdir (DIR *dir, dirent *de)
{
char flptst[] = "X:";
WCHAR drive[] = L"X:";
while (true)
{
@ -2426,8 +2427,29 @@ fhandler_cygdrive::readdir (DIR *dir, dirent *de)
}
return ENMFILE;
}
if (!is_floppy ((flptst[0] = *pdrive, flptst))
&& GetFileAttributes (pdrive) != INVALID_FILE_ATTRIBUTES)
disk_type dt = get_disk_type ((drive[0] = *pdrive, drive));
if (dt == DT_SHARE_SMB)
{
/* Calling NetUseGetInfo on SMB drives allows to fetch the
current state of the drive without trying to open a file
descriptor on the share (GetFileAttributes). This avoids
waiting for SMB timeouts. Of course, there's a downside:
If a drive becomes availabe again, it can take a couple of
minutes to recognize it. As long as this didn't happen,
the drive will not show up in the cygdrive dir. */
PUSE_INFO_1 pui1;
DWORD status;
if (NetUseGetInfo (NULL, drive, 1, (PBYTE *) &pui1) == NERR_Success)
{
status = pui1->ui1_status;
NetApiBufferFree (pui1);
if (status == USE_OK)
break;
}
}
else if (dt != DT_FLOPPY
&& GetFileAttributes (pdrive) != INVALID_FILE_ATTRIBUTES)
break;
pdrive = strchr (pdrive, '\0') + 1;
}

View File

@ -1840,13 +1840,42 @@ cygwin_umount (const char *path, unsigned flags)
return res;
}
bool
is_floppy (const char *dos)
#define is_dev(d,s) wcsncmp((d),(s),sizeof(s) - 1)
disk_type
get_disk_type (LPCWSTR dos)
{
char dev[256];
if (!QueryDosDevice (dos, dev, 256))
return false;
return ascii_strncasematch (dev, "\\Device\\Floppy", 14);
WCHAR dev[MAX_PATH], *d = dev;
if (!QueryDosDeviceW (dos, dev, MAX_PATH))
return DT_NODISK;
if (is_dev (dev, L"\\Device\\"))
{
d += 8;
switch (toupper (*d))
{
case 'C':
if (is_dev (d, L"CdRom"))
return DT_CDROM;
break;
case 'F':
if (is_dev (d, L"Floppy"))
return DT_FLOPPY;
break;
case 'H':
if (is_dev (d, L"Harddisk"))
return DT_HARDDISK;
break;
case 'L':
if (is_dev (d, L"LanmanRedirector\\"))
return DT_SHARE_SMB;
break;
case 'M':
if (is_dev (d, L"MRxNfs\\"))
return DT_SHARE_NFS;
break;
}
}
return DT_NODISK;
}
extern "C" FILE *
@ -1855,9 +1884,11 @@ setmntent (const char *filep, const char *)
_my_tls.locals.iteration = 0;
_my_tls.locals.available_drives = GetLogicalDrives ();
/* Filter floppy drives on A: and B: */
if ((_my_tls.locals.available_drives & 1) && is_floppy ("A:"))
if ((_my_tls.locals.available_drives & 1)
&& get_disk_type (L"A:") == DT_FLOPPY)
_my_tls.locals.available_drives &= ~1;
if ((_my_tls.locals.available_drives & 2) && is_floppy ("B:"))
if ((_my_tls.locals.available_drives & 2)
&& get_disk_type (L"B:") == DT_FLOPPY)
_my_tls.locals.available_drives &= ~2;
return (FILE *) filep;
}

View File

@ -1,7 +1,7 @@
/* mount.h: mount definitions.
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
2006, 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
This file is part of Cygwin.
@ -12,6 +12,18 @@ details. */
#ifndef _MOUNT_H
#define _MOUNT_H
enum disk_type
{
DT_NODISK,
DT_CDROM,
DT_FLOPPY,
DT_HARDDISK,
DT_SHARE_SMB,
DT_SHARE_NFS
};
disk_type get_disk_type (LPCWSTR);
enum fs_info_type
{
none = 0,

View File

@ -424,7 +424,6 @@ bool has_dot_last_component (const char *dir, bool test_dot_dot) __attribute__ (
int path_prefix_p (const char *path1, const char *path2, int len1,
bool caseinsensitive) __attribute__ ((regparm (3)));
bool is_floppy (const char *);
NTSTATUS file_get_fnoi (HANDLE, bool, struct _FILE_NETWORK_OPEN_INFORMATION *);
int normalize_win32_path (const char *, char *, char *&);
int normalize_posix_path (const char *, char *, char *&);