Alexandre Julliard : mountmgr: Protect the device structures with a critical section.
Alexandre Julliard
julliard at winehq.org
Thu Jul 23 09:59:25 CDT 2009
Module: wine
Branch: master
Commit: 79de2e8126a194a517ab8d6e13dfc8a005f5b43b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=79de2e8126a194a517ab8d6e13dfc8a005f5b43b
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jul 22 21:13:00 2009 +0200
mountmgr: Protect the device structures with a critical section.
---
dlls/mountmgr.sys/device.c | 66 ++++++++++++++++++++++++++++++++-----------
1 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index bdade97..03b1f89 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -89,6 +89,15 @@ static struct list volumes_list = LIST_INIT(volumes_list);
static DRIVER_OBJECT *harddisk_driver;
+static CRITICAL_SECTION device_section;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+ 0, 0, &device_section,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": device_section") }
+};
+static CRITICAL_SECTION device_section = { &critsect_debug, -1, 0, 0, 0, 0 };
+
static char *get_dosdevices_path( char **drive )
{
const char *config_dir = wine_get_config_dir();
@@ -650,37 +659,41 @@ NTSTATUS add_volume( const char *udi, const char *device, const char *mount_poin
enum device_type type, const GUID *guid )
{
struct volume *volume;
- NTSTATUS status;
+ NTSTATUS status = STATUS_SUCCESS;
TRACE( "adding %s device %s mount %s type %u uuid %s\n", debugstr_a(udi),
debugstr_a(device), debugstr_a(mount_point), type, debugstr_guid(guid) );
+ EnterCriticalSection( &device_section );
LIST_FOR_EACH_ENTRY( volume, &volumes_list, struct volume, entry )
if (volume->udi && !strcmp( udi, volume->udi )) goto found;
/* udi not found, search for a non-dynamic volume */
- if ((volume = find_matching_volume( udi, device, mount_point, type )))
- {
- set_volume_udi( volume, udi );
- }
- else if ((status = create_volume( udi, type, &volume ))) return status;
+ if ((volume = find_matching_volume( udi, device, mount_point, type ))) set_volume_udi( volume, udi );
+ else status = create_volume( udi, type, &volume );
found:
- return set_volume_info( volume, NULL, device, mount_point, type, guid );
+ if (!status) status = set_volume_info( volume, NULL, device, mount_point, type, guid );
+ LeaveCriticalSection( &device_section );
+ return status;
}
/* create a new disk volume */
NTSTATUS remove_volume( const char *udi )
{
+ NTSTATUS status = STATUS_NO_SUCH_DEVICE;
struct volume *volume;
+ EnterCriticalSection( &device_section );
LIST_FOR_EACH_ENTRY( volume, &volumes_list, struct volume, entry )
{
if (!volume->udi || strcmp( udi, volume->udi )) continue;
set_volume_udi( volume, NULL );
- return STATUS_SUCCESS;
+ status = STATUS_SUCCESS;
+ break;
}
- return STATUS_NO_SUCH_DEVICE;
+ LeaveCriticalSection( &device_section );
+ return status;
}
@@ -692,10 +705,14 @@ NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
HKEY hkey;
NTSTATUS status = STATUS_SUCCESS;
struct dos_drive *drive, *next;
- struct volume *volume = find_matching_volume( udi, device, mount_point, type );
+ struct volume *volume;
+ int notify = -1;
if (!(path = get_dosdevices_path( &p ))) return STATUS_NO_MEMORY;
+ EnterCriticalSection( &device_section );
+ volume = find_matching_volume( udi, device, mount_point, type );
+
if (letter == -1) /* auto-assign a letter */
{
letter = add_drive( device, type );
@@ -756,20 +773,25 @@ found:
RegCloseKey( hkey );
}
- if (udi) send_notify( drive->drive, DBT_DEVICEARRIVAL );
+ if (udi) notify = drive->drive;
done:
+ LeaveCriticalSection( &device_section );
RtlFreeHeap( GetProcessHeap(), 0, path );
+ if (notify != -1) send_notify( notify, DBT_DEVICEARRIVAL );
return status;
}
/* remove an existing dos drive, by letter or udi */
NTSTATUS remove_dos_device( int letter, const char *udi )
{
+ NTSTATUS status = STATUS_NO_SUCH_DEVICE;
HKEY hkey;
struct dos_drive *drive;
char *path, *p;
+ int notify = -1;
+ EnterCriticalSection( &device_section );
LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry )
{
if (udi)
@@ -797,21 +819,25 @@ NTSTATUS remove_dos_device( int letter, const char *udi )
RegCloseKey( hkey );
}
- if (udi && drive->volume->device->unix_mount)
- send_notify( drive->drive, DBT_DEVICEREMOVECOMPLETE );
+ if (udi && drive->volume->device->unix_mount) notify = drive->drive;
delete_dos_device( drive );
- return STATUS_SUCCESS;
+ status = STATUS_SUCCESS;
+ break;
}
- return STATUS_NO_SUCH_DEVICE;
+ LeaveCriticalSection( &device_section );
+ if (notify != -1) send_notify( notify, DBT_DEVICEREMOVECOMPLETE );
+ return status;
}
/* query information about an existing dos drive, by letter or udi */
NTSTATUS query_dos_device( int letter, enum device_type *type, char **device, char **mount_point )
{
+ NTSTATUS status = STATUS_NO_SUCH_DEVICE;
struct dos_drive *drive;
struct disk_device *disk_device;
+ EnterCriticalSection( &device_section );
LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry )
{
if (drive->drive != letter) continue;
@@ -819,9 +845,11 @@ NTSTATUS query_dos_device( int letter, enum device_type *type, char **device, ch
if (type) *type = disk_device->type;
if (device) *device = strdupA( disk_device->unix_device );
if (mount_point) *mount_point = strdupA( disk_device->unix_mount );
- return STATUS_SUCCESS;
+ status = STATUS_SUCCESS;
+ break;
}
- return STATUS_NO_SUCH_DEVICE;
+ LeaveCriticalSection( &device_section );
+ return status;
}
/* handler for ioctls on the harddisk device */
@@ -835,6 +863,8 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
irpsp->Parameters.DeviceIoControl.InputBufferLength,
irpsp->Parameters.DeviceIoControl.OutputBufferLength );
+ EnterCriticalSection( &device_section );
+
switch(irpsp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
@@ -869,6 +899,8 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
break;
}
+
+ LeaveCriticalSection( &device_section );
return irp->IoStatus.u.Status;
}
More information about the wine-cvs
mailing list