From 9d293a1e9be980b48544c92fb43a9e964331877d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 25 Nov 2021 19:00:21 +0100 Subject: [PATCH] mountmgr: Put the Unix helpers in a separate Unix library. Signed-off-by: Alexandre Julliard --- dlls/mountmgr.sys/Makefile.in | 1 + dlls/mountmgr.sys/device.c | 53 +++++++++++++------ dlls/mountmgr.sys/mountmgr.c | 27 +++++++--- dlls/mountmgr.sys/unixlib.c | 97 +++++++++++++++++++++++------------ dlls/mountmgr.sys/unixlib.h | 88 +++++++++++++++++++++++++++---- 5 files changed, 201 insertions(+), 65 deletions(-) diff --git a/dlls/mountmgr.sys/Makefile.in b/dlls/mountmgr.sys/Makefile.in index cf5d23301f4..75a3deefa35 100644 --- a/dlls/mountmgr.sys/Makefile.in +++ b/dlls/mountmgr.sys/Makefile.in @@ -1,4 +1,5 @@ MODULE = mountmgr.sys +UNIXLIB = mountmgr.so IMPORTS = uuid advapi32 ntoskrnl DELAYIMPORTS = user32 EXTRAINCL = $(DBUS_CFLAGS) $(HAL_CFLAGS) diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c index 187174b2bea..2be8d8cfab6 100644 --- a/dlls/mountmgr.sys/device.c +++ b/dlls/mountmgr.sys/device.c @@ -186,10 +186,11 @@ static void get_filesystem_label( struct volume *volume ) { char buffer[256], *p; ULONG size = sizeof(buffer); + struct read_volume_file_params params = { volume->device->unix_mount, ".windows-label", buffer, &size }; volume->label[0] = 0; if (!volume->device->unix_mount) return; - if (read_volume_file( volume->device->unix_mount, ".windows-label", buffer, &size )) return; + if (MOUNTMGR_CALL( read_volume_file, ¶ms )) return; p = buffer + size; while (p > buffer && (p[-1] == ' ' || p[-1] == '\r' || p[-1] == '\n')) p--; @@ -203,10 +204,11 @@ static void get_filesystem_serial( struct volume *volume ) { char buffer[32]; ULONG size = sizeof(buffer); + struct read_volume_file_params params = { volume->device->unix_mount, ".windows-serial", buffer, &size }; volume->serial = 0; if (!volume->device->unix_mount) return; - if (read_volume_file( volume->device->unix_mount, ".windows-serial", buffer, &size )) return; + if (MOUNTMGR_CALL( read_volume_file, ¶ms )) return; buffer[size] = 0; volume->serial = strtoul( buffer, NULL, 16 ); @@ -974,8 +976,9 @@ static void set_dos_devices_disk_serial( struct disk_device *device ) { unsigned int devices; struct dos_drive *drive; + struct get_volume_dos_devices_params params = { device->unix_mount, &devices }; - if (!device->serial || !device->unix_mount || get_volume_dos_devices( device->unix_mount, &devices )) + if (!device->serial || !device->unix_mount || MOUNTMGR_CALL( get_volume_dos_devices, ¶ms )) return; LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry ) @@ -1108,12 +1111,15 @@ static void create_drive_devices(void) { char link[4096], unix_dev[4096]; char *device = NULL; + struct get_dosdev_symlink_params params = { dosdev, link, sizeof(link) }; dosdev[0] = 'a' + i; dosdev[2] = 0; - if (get_dosdev_symlink( dosdev, link, sizeof(link) )) continue; + if (MOUNTMGR_CALL( get_dosdev_symlink, ¶ms )) continue; dosdev[2] = ':'; - if (!get_dosdev_symlink( dosdev, unix_dev, sizeof(unix_dev) )) device = unix_dev; + params.dest = unix_dev; + params.size = sizeof(unix_dev); + if (!MOUNTMGR_CALL( get_dosdev_symlink, ¶ms )) device = unix_dev; drive_type = i < 2 ? DEVICE_FLOPPY : DEVICE_HARDDISK_VOL; if (drives_key) @@ -1310,7 +1316,8 @@ NTSTATUS add_dos_device( int letter, const char *udi, const char *device, if (letter == -1) /* auto-assign a letter */ { - if ((status = add_drive( device, type, &letter ))) goto done; + struct add_drive_params params = { device, type, &letter }; + if ((status = MOUNTMGR_CALL( add_drive, ¶ms ))) goto done; LIST_FOR_EACH_ENTRY_SAFE( drive, next, &drives_list, struct dos_drive, entry ) { @@ -1320,16 +1327,21 @@ NTSTATUS add_dos_device( int letter, const char *udi, const char *device, } else /* simply reset the device symlink */ { + struct set_dosdev_symlink_params params = { dosdev, device }; + LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry ) if (drive->drive == letter) break; dosdev[0] = 'a' + letter; - if (&drive->entry == &drives_list) set_dosdev_symlink( dosdev, device ); + if (&drive->entry == &drives_list) + { + MOUNTMGR_CALL( set_dosdev_symlink, ¶ms ); + } else { if (!device || !drive->volume->device->unix_device || strcmp( device, drive->volume->device->unix_device )) - set_dosdev_symlink( dosdev, device ); + MOUNTMGR_CALL( set_dosdev_symlink, ¶ms ); delete_dos_device( drive ); } } @@ -1343,7 +1355,10 @@ found: dosdev[0] = 'a' + drive->drive; dosdev[2] = 0; if (!mount_point || !volume->device->unix_mount || strcmp( mount_point, volume->device->unix_mount )) - set_dosdev_symlink( dosdev, mount_point ); + { + struct set_dosdev_symlink_params params = { dosdev, mount_point }; + MOUNTMGR_CALL( set_dosdev_symlink, ¶ms ); + } set_volume_info( volume, drive, device, mount_point, type, guid, NULL ); TRACE( "added device %c: udi %s for %s on %s type %u\n", @@ -1388,6 +1403,8 @@ NTSTATUS remove_dos_device( int letter, const char *udi ) EnterCriticalSection( &device_section ); LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry ) { + struct set_dosdev_symlink_params params = { dosdev, NULL }; + if (udi) { if (!drive->volume->udi) continue; @@ -1397,7 +1414,7 @@ NTSTATUS remove_dos_device( int letter, const char *udi ) else if (drive->drive != letter) continue; dosdev[0] = 'a' + drive->drive; - set_dosdev_symlink( dosdev, NULL ); + MOUNTMGR_CALL( set_dosdev_symlink, ¶ms ); /* clear the registry key too */ if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, drives_keyW, &hkey )) @@ -1455,7 +1472,8 @@ static struct volume *find_volume_by_unixdev( ULONGLONG unix_dev ) LIST_FOR_EACH_ENTRY( volume, &volumes_list, struct volume, entry ) { - if (!volume->device->unix_device || !match_unixdev( volume->device->unix_device, unix_dev )) + struct match_unixdev_params params = { volume->device->unix_device, unix_dev }; + if (!volume->device->unix_device || !MOUNTMGR_CALL( match_unixdev, ¶ms )) continue; TRACE( "found matching volume %s\n", debugstr_guid(&volume->guid) ); @@ -1875,6 +1893,10 @@ static BOOL create_port_device( DRIVER_OBJECT *driver, int n, const char *unix_p UNICODE_STRING nt_name, symlink_name, default_name; DEVICE_OBJECT *dev_obj; NTSTATUS status; + struct set_dosdev_symlink_params params = { dosdevices_path, unix_path }; + + /* create DOS device */ + if (MOUNTMGR_CALL( set_dosdev_symlink, ¶ms )) return FALSE; if (driver == serial_driver) { @@ -1895,9 +1917,6 @@ static BOOL create_port_device( DRIVER_OBJECT *driver, int n, const char *unix_p sprintfW( dos_name, dos_name_format, n ); - /* create DOS device */ - if (set_dosdev_symlink( dosdevices_path, unix_path )) return FALSE; - /* create NT device */ sprintfW( nt_buffer, nt_name_format, n - 1 ); RtlInitUnicodeString( &nt_name, nt_buffer ); @@ -2012,11 +2031,12 @@ static void create_port_devices( DRIVER_OBJECT *driver, const char *devices ) NTSTATUS WINAPI serial_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) { char devices[4096]; + struct detect_ports_params params = { devices, sizeof(devices) }; serial_driver = driver; /* TODO: fill in driver->MajorFunction */ - detect_serial_ports( devices, sizeof(devices) ); + MOUNTMGR_CALL( detect_serial_ports, ¶ms ); create_port_devices( driver, devices ); return STATUS_SUCCESS; @@ -2026,11 +2046,12 @@ NTSTATUS WINAPI serial_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path NTSTATUS WINAPI parallel_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) { char devices[4096]; + struct detect_ports_params params = { devices, sizeof(devices) }; parallel_driver = driver; /* TODO: fill in driver->MajorFunction */ - detect_parallel_ports( devices, sizeof(devices) ); + MOUNTMGR_CALL( detect_parallel_ports, ¶ms ); create_port_devices( driver, devices ); return STATUS_SUCCESS; diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c index be3162cdb5f..0869e96766a 100644 --- a/dlls/mountmgr.sys/mountmgr.c +++ b/dlls/mountmgr.sys/mountmgr.c @@ -50,6 +50,8 @@ struct mount_point static struct list mount_points_list = LIST_INIT(mount_points_list); static HKEY mount_key; +unixlib_handle_t mountmgr_handle = 0; + void set_mount_point_id( struct mount_point *mount, const void *id, unsigned int id_len ) { RtlFreeHeap( GetProcessHeap(), 0, mount->id ); @@ -286,6 +288,7 @@ static NTSTATUS define_shell_folder( const void *in_buff, SIZE_T insize ) NTSTATUS status; ULONG size = 256; char *buffer = NULL, *backup = NULL; + struct set_shell_folder_params params; if (input->folder_offset >= insize || input->folder_size > insize - input->folder_offset || input->symlink_offset >= insize) @@ -328,7 +331,10 @@ static NTSTATUS define_shell_folder( const void *in_buff, SIZE_T insize ) strcat( backup, ".backup" ); } - status = set_shell_folder( buffer, backup, link ); + params.folder = buffer; + params.backup = backup; + params.link = link; + status = MOUNTMGR_CALL( set_shell_folder, ¶ms ); done: HeapFree( GetProcessHeap(), 0, buffer ); @@ -354,14 +360,17 @@ static NTSTATUS query_shell_folder( void *buff, SIZE_T insize, SIZE_T outsize, I { if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size ))) return STATUS_NO_MEMORY; status = wine_nt_to_unix_file_name( &attr, buffer, &size, FILE_OPEN ); - if (!status) break; + if (!status) + { + struct get_shell_folder_params params = { buffer, output, outsize }; + status = MOUNTMGR_CALL( get_shell_folder, ¶ms ); + if (!status) iosb->Information = strlen(output) + 1; + break; + } + if (status != STATUS_BUFFER_TOO_SMALL) break; HeapFree( GetProcessHeap(), 0, buffer ); - if (status != STATUS_BUFFER_TOO_SMALL) return status; } - status = get_shell_folder( buffer, output, outsize ); - if (!status) iosb->Information = strlen(output) + 1; - HeapFree( GetProcessHeap(), 0, buffer ); return status; } @@ -593,6 +602,7 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) HKEY wow64_ports_key = NULL; #endif + void *instance; UNICODE_STRING nameW, linkW; DEVICE_OBJECT *device; HKEY devicemap_key; @@ -600,6 +610,11 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) TRACE( "%s\n", debugstr_w(path->Buffer) ); + RtlPcToFileHeader( DriverEntry, &instance ); + status = NtQueryVirtualMemory( GetCurrentProcess(), instance, MemoryWineUnixFuncs, + &mountmgr_handle, sizeof(mountmgr_handle), NULL ); + if (status) return status; + driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = mountmgr_ioctl; RtlInitUnicodeString( &nameW, device_mountmgrW ); diff --git a/dlls/mountmgr.sys/unixlib.c b/dlls/mountmgr.sys/unixlib.c index 8e6378e5637..7b14e2a8a15 100644 --- a/dlls/mountmgr.sys/unixlib.c +++ b/dlls/mountmgr.sys/unixlib.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#if 0 +#pragma makedep unix +#endif + #include "config.h" #include @@ -84,21 +88,22 @@ static void detect_devices( const char **paths, char *names, ULONG size ) } /* find or create a DOS drive for the corresponding Unix device */ -NTSTATUS add_drive( const char *device, enum device_type type, int *letter ) +static NTSTATUS add_drive( void *args ) { + const struct add_drive_params *params = args; char *path, *p; char in_use[26]; struct stat dev_st, drive_st; int drive, first, last, avail = 0; - if (stat( device, &dev_st ) == -1 || !is_valid_device( &dev_st )) return STATUS_NO_SUCH_DEVICE; + if (stat( params->device, &dev_st ) == -1 || !is_valid_device( &dev_st )) return STATUS_NO_SUCH_DEVICE; if (!(path = get_dosdevices_path( "a::" ))) return STATUS_NO_MEMORY; p = path + strlen(path) - 3; memset( in_use, 0, sizeof(in_use) ); - switch (type) + switch (params->type) { case DEVICE_FLOPPY: first = 0; @@ -148,7 +153,7 @@ NTSTATUS add_drive( const char *device, enum device_type type, int *letter ) /* try to use the one we found */ drive = avail; *p = 'a' + drive; - if (symlink( device, path ) != -1) goto done; + if (symlink( params->device, path ) != -1) goto done; /* failed, retry the search */ } } @@ -157,36 +162,38 @@ NTSTATUS add_drive( const char *device, enum device_type type, int *letter ) done: free( path ); - *letter = drive; + *params->letter = drive; return STATUS_SUCCESS; } -NTSTATUS get_dosdev_symlink( const char *dev, char *buffer, ULONG size ) +static NTSTATUS get_dosdev_symlink( void *args ) { + const struct get_dosdev_symlink_params *params = args; char *path; int ret; - if (!(path = get_dosdevices_path( dev ))) return STATUS_NO_MEMORY; + if (!(path = get_dosdevices_path( params->dev ))) return STATUS_NO_MEMORY; - ret = readlink( path, buffer, size ); + ret = readlink( path, params->dest, params->size ); free( path ); if (ret == -1) return STATUS_NO_SUCH_DEVICE; - if (ret == size) return STATUS_BUFFER_TOO_SMALL; - buffer[ret] = 0; + if (ret == params->size) return STATUS_BUFFER_TOO_SMALL; + params->dest[ret] = 0; return STATUS_SUCCESS; } -NTSTATUS set_dosdev_symlink( const char *dev, const char *dest ) +static NTSTATUS set_dosdev_symlink( void *args ) { + const struct set_dosdev_symlink_params *params = args; char *path; NTSTATUS status = STATUS_SUCCESS; - if (!(path = get_dosdevices_path( dev ))) return STATUS_NO_MEMORY; + if (!(path = get_dosdevices_path( params->dev ))) return STATUS_NO_MEMORY; - if (dest && dest[0]) + if (params->dest && params->dest[0]) { unlink( path ); - if (symlink( dest, path ) == -1) status = STATUS_ACCESS_DENIED; + if (symlink( params->dest, path ) == -1) status = STATUS_ACCESS_DENIED; } else unlink( path ); @@ -194,31 +201,33 @@ NTSTATUS set_dosdev_symlink( const char *dev, const char *dest ) return status; } -NTSTATUS get_volume_dos_devices( const char *mount_point, unsigned int *dosdev ) +static NTSTATUS get_volume_dos_devices( void *args ) { + const struct get_volume_dos_devices_params *params = args; struct stat dev_st, drive_st; char *path; int i; - if (stat( mount_point, &dev_st ) == -1) return STATUS_NO_SUCH_DEVICE; + if (stat( params->mount_point, &dev_st ) == -1) return STATUS_NO_SUCH_DEVICE; if (!(path = get_dosdevices_path( "a:" ))) return STATUS_NO_MEMORY; - *dosdev = 0; + *params->dosdev = 0; for (i = 0; i < 26; i++) { path[strlen(path) - 2] = 'a' + i; - if (stat( path, &drive_st ) != -1 && drive_st.st_rdev == dev_st.st_rdev) *dosdev |= 1 << i; + if (stat( path, &drive_st ) != -1 && drive_st.st_rdev == dev_st.st_rdev) *params->dosdev |= 1 << i; } free( path ); return STATUS_SUCCESS; } -NTSTATUS read_volume_file( const char *volume, const char *file, void *buffer, ULONG *size ) +static NTSTATUS read_volume_file( void *args ) { + const struct read_volume_file_params *params = args; int ret, fd = -1; - char *name = malloc( strlen(volume) + strlen(file) + 2 ); + char *name = malloc( strlen(params->volume) + strlen(params->file) + 2 ); - sprintf( name, "%s/%s", volume, file ); + sprintf( name, "%s/%s", params->volume, params->file ); if (name[0] != '/') { @@ -230,22 +239,24 @@ NTSTATUS read_volume_file( const char *volume, const char *file, void *buffer, U free( name ); if (fd == -1) return STATUS_NO_SUCH_FILE; - ret = read( fd, buffer, *size ); + ret = read( fd, params->buffer, *params->size ); close( fd ); if (ret == -1) return STATUS_NO_SUCH_FILE; - *size = ret; + *params->size = ret; return STATUS_SUCCESS; } -BOOL match_unixdev( const char *device, ULONGLONG unix_dev ) +static NTSTATUS match_unixdev( void *args ) { + const struct match_unixdev_params *params = args; struct stat st; - return !stat( device, &st ) && st.st_rdev == unix_dev; + return !stat( params->device, &st ) && st.st_rdev == params->unix_dev; } -NTSTATUS detect_serial_ports( char *names, ULONG size ) +static NTSTATUS detect_serial_ports( void *args ) { + const struct detect_ports_params *params = args; static const char *paths[] = { #ifdef linux @@ -260,12 +271,13 @@ NTSTATUS detect_serial_ports( char *names, ULONG size ) NULL }; - detect_devices( paths, names, size ); + detect_devices( paths, params->names, params->size ); return STATUS_SUCCESS; } -NTSTATUS detect_parallel_ports( char *names, ULONG size ) +static NTSTATUS detect_parallel_ports( void *args ) { + const struct detect_ports_params *params = args; static const char *paths[] = { #ifdef linux @@ -274,12 +286,16 @@ NTSTATUS detect_parallel_ports( char *names, ULONG size ) NULL }; - detect_devices( paths, names, size ); + detect_devices( paths, params->names, params->size ); return STATUS_SUCCESS; } -NTSTATUS set_shell_folder( const char *folder, const char *backup, const char *link ) +static NTSTATUS set_shell_folder( void *args ) { + const struct set_shell_folder_params *params = args; + const char *folder = params->folder; + const char *backup = params->backup; + const char *link = params->link; struct stat st; const char *home; char *homelink = NULL; @@ -333,11 +349,26 @@ done: return status; } -NTSTATUS get_shell_folder( const char *folder, char *buffer, ULONG size ) +static NTSTATUS get_shell_folder( void *args ) { - int ret = readlink( folder, buffer, size - 1 ); + const struct get_shell_folder_params *params = args; + int ret = readlink( params->folder, params->buffer, params->size - 1 ); if (ret < 0) return STATUS_OBJECT_NAME_NOT_FOUND; - buffer[ret] = 0; + params->buffer[ret] = 0; return STATUS_SUCCESS; } + +const unixlib_entry_t __wine_unix_call_funcs[] = +{ + add_drive, + get_dosdev_symlink, + set_dosdev_symlink, + get_volume_dos_devices, + read_volume_file, + match_unixdev, + detect_serial_ports, + detect_parallel_ports, + set_shell_folder, + get_shell_folder, +}; diff --git a/dlls/mountmgr.sys/unixlib.h b/dlls/mountmgr.sys/unixlib.h index 15ad7bd32eb..e7a72857846 100644 --- a/dlls/mountmgr.sys/unixlib.h +++ b/dlls/mountmgr.sys/unixlib.h @@ -19,17 +19,85 @@ */ #include "mountmgr.h" +#include "wine/unixlib.h" -extern NTSTATUS add_drive( const char *device, enum device_type type, int *letter ) DECLSPEC_HIDDEN; -extern NTSTATUS get_dosdev_symlink( const char *dev, char *dest, ULONG size ) DECLSPEC_HIDDEN; -extern NTSTATUS set_dosdev_symlink( const char *dev, const char *dest ) DECLSPEC_HIDDEN; -extern NTSTATUS get_volume_dos_devices( const char *mount_point, unsigned int *dosdev ) DECLSPEC_HIDDEN; -extern NTSTATUS read_volume_file( const char *volume, const char *file, void *buffer, ULONG *size ) DECLSPEC_HIDDEN; -extern BOOL match_unixdev( const char *device, ULONGLONG unix_dev ) DECLSPEC_HIDDEN; -extern NTSTATUS detect_serial_ports( char *names, ULONG size ) DECLSPEC_HIDDEN; -extern NTSTATUS detect_parallel_ports( char *names, ULONG size ) DECLSPEC_HIDDEN; -extern NTSTATUS set_shell_folder( const char *folder, const char *backup, const char *link ) DECLSPEC_HIDDEN; -extern NTSTATUS get_shell_folder( const char *folder, char *buffer, ULONG size ) DECLSPEC_HIDDEN; +struct add_drive_params +{ + const char *device; + enum device_type type; + int *letter; +}; + +struct get_dosdev_symlink_params +{ + const char *dev; + char *dest; + ULONG size; +}; + +struct set_dosdev_symlink_params +{ + const char *dev; + const char *dest; +}; + +struct get_volume_dos_devices_params +{ + const char *mount_point; + unsigned int *dosdev; +}; + +struct read_volume_file_params +{ + const char *volume; + const char *file; + void *buffer; + ULONG *size; +}; + +struct match_unixdev_params +{ + const char *device; + ULONGLONG unix_dev; +}; + +struct detect_ports_params +{ + char *names; + ULONG size; +}; + +struct set_shell_folder_params +{ + const char *folder; + const char *backup; + const char *link; +}; + +struct get_shell_folder_params +{ + const char *folder; + char *buffer; + ULONG size; +}; + +enum mountmgr_funcs +{ + unix_add_drive, + unix_get_dosdev_symlink, + unix_set_dosdev_symlink, + unix_get_volume_dos_devices, + unix_read_volume_file, + unix_match_unixdev, + unix_detect_serial_ports, + unix_detect_parallel_ports, + unix_set_shell_folder, + unix_get_shell_folder, +}; + +extern unixlib_handle_t mountmgr_handle; + +#define MOUNTMGR_CALL( func, params ) __wine_unix_call( mountmgr_handle, unix_ ## func, params ) extern NTSTATUS query_symbol_file( void *buff, ULONG insize, ULONG outsize, ULONG *info ) DECLSPEC_HIDDEN; extern NTSTATUS read_credential( void *buff, ULONG insize, ULONG outsize, ULONG *info ) DECLSPEC_HIDDEN;