Module: wine Branch: master Commit: 79de2e8126a194a517ab8d6e13dfc8a005f5b43b URL: http://source.winehq.org/git/wine.git/?a=commit;h=79de2e8126a194a517ab8d6e13...
Author: Alexandre Julliard julliard@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; }