Commit 086e9e0e authored by Alexandre Julliard's avatar Alexandre Julliard

mountmgr: Add some helpers to abstract the Unix calls from mountmgr.c.

parent 9c587c50
......@@ -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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment