ntdll: Cache the DOS drives stat info for up to one second.
This commit is contained in:
parent
d7892ccf2b
commit
7fd1ad5ffa
|
@ -226,6 +226,60 @@ static char *get_default_lpt_device( int num )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DIR_get_drives_info
|
||||
*
|
||||
* Retrieve device/inode number for all the drives. Helper for find_drive_root.
|
||||
*/
|
||||
unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES] )
|
||||
{
|
||||
static struct drive_info cache[MAX_DOS_DRIVES];
|
||||
static time_t last_update;
|
||||
static unsigned int nb_drives;
|
||||
unsigned int ret;
|
||||
time_t now = time(NULL);
|
||||
|
||||
RtlEnterCriticalSection( &dir_section );
|
||||
if (now != last_update)
|
||||
{
|
||||
const char *config_dir = wine_get_config_dir();
|
||||
char *buffer, *p;
|
||||
struct stat st;
|
||||
unsigned int i;
|
||||
|
||||
if ((buffer = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||
strlen(config_dir) + sizeof("/dosdevices/a:") )))
|
||||
{
|
||||
strcpy( buffer, config_dir );
|
||||
strcat( buffer, "/dosdevices/a:" );
|
||||
p = buffer + strlen(buffer) - 2;
|
||||
|
||||
for (i = nb_drives = 0; i < MAX_DOS_DRIVES; i++)
|
||||
{
|
||||
*p = 'a' + i;
|
||||
if (!stat( buffer, &st ))
|
||||
{
|
||||
cache[i].dev = st.st_dev;
|
||||
cache[i].ino = st.st_ino;
|
||||
nb_drives++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cache[i].dev = 0;
|
||||
cache[i].ino = 0;
|
||||
}
|
||||
}
|
||||
RtlFreeHeap( GetProcessHeap(), 0, buffer );
|
||||
}
|
||||
last_update = now;
|
||||
}
|
||||
memcpy( info, cache, sizeof(cache) );
|
||||
ret = nb_drives;
|
||||
RtlLeaveCriticalSection( &dir_section );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* parse_mount_entries
|
||||
*
|
||||
|
|
|
@ -29,6 +29,14 @@
|
|||
|
||||
#define MAX_NT_PATH_LENGTH 277
|
||||
|
||||
#define MAX_DOS_DRIVES 26
|
||||
|
||||
struct drive_info
|
||||
{
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
};
|
||||
|
||||
/* exceptions */
|
||||
extern void wait_suspend( CONTEXT *context );
|
||||
extern void WINAPI __regs_RtlRaiseException( PEXCEPTION_RECORD, PCONTEXT );
|
||||
|
@ -113,6 +121,7 @@ extern NTSTATUS FILE_GetNtStatus(void);
|
|||
extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name );
|
||||
extern NTSTATUS DIR_unmount_device( HANDLE handle );
|
||||
extern NTSTATUS DIR_get_unix_cwd( char **cwd );
|
||||
extern unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES] );
|
||||
|
||||
/* virtual memory */
|
||||
extern NTSTATUS VIRTUAL_HandleFault(LPCVOID addr);
|
||||
|
|
|
@ -50,52 +50,6 @@ static const WCHAR UncPfxW[] = {'U','N','C','\\',0};
|
|||
|
||||
#define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
|
||||
|
||||
#define MAX_DOS_DRIVES 26
|
||||
|
||||
struct drive_info
|
||||
{
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* get_drives_info
|
||||
*
|
||||
* Retrieve device/inode number for all the drives. Helper for find_drive_root.
|
||||
*/
|
||||
static inline int get_drives_info( struct drive_info info[MAX_DOS_DRIVES] )
|
||||
{
|
||||
const char *config_dir = wine_get_config_dir();
|
||||
char *buffer, *p;
|
||||
struct stat st;
|
||||
int i, ret;
|
||||
|
||||
buffer = RtlAllocateHeap( GetProcessHeap(), 0, strlen(config_dir) + sizeof("/dosdevices/a:") );
|
||||
if (!buffer) return 0;
|
||||
strcpy( buffer, config_dir );
|
||||
strcat( buffer, "/dosdevices/a:" );
|
||||
p = buffer + strlen(buffer) - 2;
|
||||
|
||||
for (i = ret = 0; i < MAX_DOS_DRIVES; i++)
|
||||
{
|
||||
*p = 'a' + i;
|
||||
if (!stat( buffer, &st ))
|
||||
{
|
||||
info[i].dev = st.st_dev;
|
||||
info[i].ino = st.st_ino;
|
||||
ret++;
|
||||
}
|
||||
else
|
||||
{
|
||||
info[i].dev = 0;
|
||||
info[i].ino = 0;
|
||||
}
|
||||
}
|
||||
RtlFreeHeap( GetProcessHeap(), 0, buffer );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* remove_last_componentA
|
||||
*
|
||||
|
@ -149,7 +103,7 @@ static NTSTATUS find_drive_rootA( LPCSTR *ppath, unsigned int len, int *drive_re
|
|||
struct drive_info info[MAX_DOS_DRIVES];
|
||||
|
||||
/* get device and inode of all drives */
|
||||
if (!get_drives_info( info )) return STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
if (!DIR_get_drives_info( info )) return STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
|
||||
/* strip off trailing slashes */
|
||||
while (len > 1 && path[len - 1] == '/') len--;
|
||||
|
@ -240,7 +194,7 @@ static int find_drive_rootW( LPCWSTR *ppath )
|
|||
struct drive_info info[MAX_DOS_DRIVES];
|
||||
|
||||
/* get device and inode of all drives */
|
||||
if (!get_drives_info( info )) return -1;
|
||||
if (!DIR_get_drives_info( info )) return -1;
|
||||
|
||||
/* strip off trailing slashes */
|
||||
lenW = strlenW(path);
|
||||
|
|
Loading…
Reference in New Issue