Alexandre Julliard : ntdll: Cache the DOS drives stat info for up to one second.
Alexandre Julliard
julliard at winehq.org
Fri Oct 19 08:35:38 CDT 2007
Module: wine
Branch: master
Commit: 7fd1ad5ffaed038dd046dbdffdd2a66e5e6c6e67
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7fd1ad5ffaed038dd046dbdffdd2a66e5e6c6e67
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Oct 18 15:16:07 2007 +0200
ntdll: Cache the DOS drives stat info for up to one second.
---
dlls/ntdll/directory.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/ntdll_misc.h | 9 +++++++
dlls/ntdll/path.c | 50 +-----------------------------------------
3 files changed, 65 insertions(+), 48 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 894d336..9288d31 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -227,6 +227,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
*
* Parse mount entries looking for a given device. Helper for get_default_drive_device.
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 05df507..4f64421 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -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);
diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c
index a42682d..6f161a3 100644
--- a/dlls/ntdll/path.c
+++ b/dlls/ntdll/path.c
@@ -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);
More information about the wine-cvs
mailing list