mountmgr: Add some helpers to abstract the Unix calls from mountmgr.c.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9c587c5099
commit
086e9e0eda
|
@ -33,14 +33,12 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#define NONAMELESSUNION
|
||||
|
||||
#include "mountmgr.h"
|
||||
#include "winreg.h"
|
||||
#include "unixlib.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
@ -297,9 +295,7 @@ static NTSTATUS define_shell_folder( const void *in_buff, SIZE_T insize )
|
|||
UNICODE_STRING name;
|
||||
NTSTATUS status;
|
||||
ULONG size = 256;
|
||||
const char *home;
|
||||
char *buffer = NULL, *backup = NULL, *homelink = NULL;
|
||||
struct stat st;
|
||||
char *buffer = NULL, *backup = NULL;
|
||||
|
||||
if (input->folder_offset >= insize || input->folder_size > insize - input->folder_offset ||
|
||||
input->symlink_offset >= insize)
|
||||
|
@ -313,22 +309,6 @@ static NTSTATUS define_shell_folder( const void *in_buff, SIZE_T insize )
|
|||
if (!link[0]) link = NULL;
|
||||
}
|
||||
|
||||
if (link && (!strcmp( link, "$HOME" ) || !strncmp( link, "$HOME/", 6 )) && (home = getenv( "HOME" )))
|
||||
{
|
||||
link += 5;
|
||||
homelink = HeapAlloc( GetProcessHeap(), 0, strlen(home) + strlen(link) + 1 );
|
||||
strcpy( homelink, home );
|
||||
strcat( homelink, link );
|
||||
link = homelink;
|
||||
}
|
||||
|
||||
/* ignore nonexistent link targets */
|
||||
if (link && (stat( link, &st ) || !S_ISDIR( st.st_mode )))
|
||||
{
|
||||
status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
name.Buffer = (WCHAR *)((char *)in_buff + input->folder_offset);
|
||||
name.Length = input->folder_size;
|
||||
InitializeObjectAttributes( &attr, &name, 0, 0, NULL );
|
||||
|
@ -358,37 +338,11 @@ static NTSTATUS define_shell_folder( const void *in_buff, SIZE_T insize )
|
|||
strcat( backup, ".backup" );
|
||||
}
|
||||
|
||||
if (!lstat( buffer, &st )) /* move old folder/link out of the way */
|
||||
{
|
||||
if (S_ISLNK( st.st_mode ))
|
||||
{
|
||||
unlink( buffer );
|
||||
}
|
||||
else if (link && S_ISDIR( st.st_mode ))
|
||||
{
|
||||
if (rmdir( buffer )) /* non-empty dir, try to make a backup */
|
||||
{
|
||||
if (!backup || rename( buffer, backup ))
|
||||
{
|
||||
status = STATUS_OBJECT_NAME_COLLISION;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
else goto done; /* nothing to do, folder already exists */
|
||||
}
|
||||
|
||||
if (link) symlink( link, buffer );
|
||||
else
|
||||
{
|
||||
if (backup && !lstat( backup, &st ) && S_ISDIR( st.st_mode )) rename( backup, buffer );
|
||||
else mkdir( buffer, 0777 );
|
||||
}
|
||||
status = set_shell_folder( buffer, backup, link );
|
||||
|
||||
done:
|
||||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
HeapFree( GetProcessHeap(), 0, backup );
|
||||
HeapFree( GetProcessHeap(), 0, homelink );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -401,7 +355,6 @@ static NTSTATUS query_shell_folder( void *buff, SIZE_T insize, SIZE_T outsize, I
|
|||
NTSTATUS status;
|
||||
ULONG size = 256;
|
||||
char *buffer;
|
||||
int ret;
|
||||
|
||||
name.Buffer = buff;
|
||||
name.Length = insize;
|
||||
|
@ -415,13 +368,9 @@ static NTSTATUS query_shell_folder( void *buff, SIZE_T insize, SIZE_T outsize, I
|
|||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
if (status != STATUS_BUFFER_TOO_SMALL) return status;
|
||||
}
|
||||
ret = readlink( buffer, output, outsize - 1 );
|
||||
if (ret >= 0)
|
||||
{
|
||||
output[ret] = 0;
|
||||
iosb->Information = ret + 1;
|
||||
}
|
||||
else status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
status = get_shell_folder( buffer, output, outsize );
|
||||
if (!status) iosb->Information = strlen(output) + 1;
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
return status;
|
||||
|
|
|
@ -277,3 +277,67 @@ NTSTATUS detect_parallel_ports( char *names, ULONG size )
|
|||
detect_devices( paths, names, size );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS set_shell_folder( const char *folder, const char *backup, const char *link )
|
||||
{
|
||||
struct stat st;
|
||||
const char *home;
|
||||
char *homelink = NULL;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
if (link && (!strcmp( link, "$HOME" ) || !strncmp( link, "$HOME/", 6 )) && (home = getenv( "HOME" )))
|
||||
{
|
||||
link += 5;
|
||||
homelink = malloc( strlen(home) + strlen(link) + 1 );
|
||||
strcpy( homelink, home );
|
||||
strcat( homelink, link );
|
||||
link = homelink;
|
||||
}
|
||||
|
||||
/* ignore nonexistent link targets */
|
||||
if (link && (stat( link, &st ) || !S_ISDIR( st.st_mode )))
|
||||
{
|
||||
status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!lstat( folder, &st )) /* move old folder/link out of the way */
|
||||
{
|
||||
if (S_ISLNK( st.st_mode ))
|
||||
{
|
||||
unlink( folder );
|
||||
}
|
||||
else if (link && S_ISDIR( st.st_mode ))
|
||||
{
|
||||
if (rmdir( folder )) /* non-empty dir, try to make a backup */
|
||||
{
|
||||
if (!backup || rename( folder, backup ))
|
||||
{
|
||||
status = STATUS_OBJECT_NAME_COLLISION;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
else goto done; /* nothing to do, folder already exists */
|
||||
}
|
||||
|
||||
if (link) symlink( link, folder );
|
||||
else
|
||||
{
|
||||
if (backup && !lstat( backup, &st ) && S_ISDIR( st.st_mode )) rename( backup, folder );
|
||||
else mkdir( folder, 0777 );
|
||||
}
|
||||
|
||||
done:
|
||||
free( homelink );
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS get_shell_folder( const char *folder, char *buffer, ULONG size )
|
||||
{
|
||||
int ret = readlink( folder, buffer, size - 1 );
|
||||
|
||||
if (ret < 0) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
buffer[ret] = 0;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -28,3 +28,5 @@ extern NTSTATUS read_volume_file( const char *volume, const char *file, void *bu
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue