Commit 4e98b081 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

kernel32: Reimplement CreateHardLink() on top of NtSetInformationFile(FileLinkInformation).

parent ee31a622
...@@ -663,10 +663,13 @@ BOOL WINAPI MoveFileA( LPCSTR source, LPCSTR dest ) ...@@ -663,10 +663,13 @@ BOOL WINAPI MoveFileA( LPCSTR source, LPCSTR dest )
BOOL WINAPI CreateHardLinkW(LPCWSTR lpFileName, LPCWSTR lpExistingFileName, BOOL WINAPI CreateHardLinkW(LPCWSTR lpFileName, LPCWSTR lpExistingFileName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes) LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{ {
NTSTATUS status;
UNICODE_STRING ntDest, ntSource; UNICODE_STRING ntDest, ntSource;
ANSI_STRING unixDest, unixSource; FILE_LINK_INFORMATION *info = NULL;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
BOOL ret = FALSE; BOOL ret = FALSE;
HANDLE file;
ULONG size;
TRACE("(%s, %s, %p)\n", debugstr_w(lpFileName), TRACE("(%s, %s, %p)\n", debugstr_w(lpFileName),
debugstr_w(lpExistingFileName), lpSecurityAttributes); debugstr_w(lpExistingFileName), lpSecurityAttributes);
...@@ -679,37 +682,30 @@ BOOL WINAPI CreateHardLinkW(LPCWSTR lpFileName, LPCWSTR lpExistingFileName, ...@@ -679,37 +682,30 @@ BOOL WINAPI CreateHardLinkW(LPCWSTR lpFileName, LPCWSTR lpExistingFileName,
goto err; goto err;
} }
unixSource.Buffer = unixDest.Buffer = NULL; size = offsetof( FILE_LINK_INFORMATION, FileName ) + ntDest.Length;
status = wine_nt_to_unix_file_name( &ntSource, &unixSource, FILE_OPEN, FALSE ); if (!(info = HeapAlloc( GetProcessHeap(), 0, size )))
if (!status)
{ {
status = wine_nt_to_unix_file_name( &ntDest, &unixDest, FILE_CREATE, FALSE ); SetLastError( ERROR_OUTOFMEMORY );
if (!status) /* destination must not exist */ goto err;
{
status = STATUS_OBJECT_NAME_EXISTS;
} else if (status == STATUS_NO_SUCH_FILE)
{
status = STATUS_SUCCESS;
}
} }
if (status) InitializeObjectAttributes( &attr, &ntSource, OBJ_CASE_INSENSITIVE, 0, NULL );
SetLastError( RtlNtStatusToDosError(status) ); if (!(ret = set_ntstatus( NtOpenFile( &file, SYNCHRONIZE, &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE,
else if (!link( unixSource.Buffer, unixDest.Buffer )) FILE_SYNCHRONOUS_IO_NONALERT ) )))
{ goto err;
TRACE("Hardlinked '%s' to '%s'\n", debugstr_a( unixDest.Buffer ),
debugstr_a( unixSource.Buffer )); info->ReplaceIfExists = FALSE;
ret = TRUE; info->RootDirectory = NULL;
} info->FileNameLength = ntDest.Length;
else memcpy( info->FileName, ntDest.Buffer, ntDest.Length );
FILE_SetDosError(); ret = set_ntstatus( NtSetInformationFile( file, &io, info, size, FileLinkInformation ) );
RtlFreeAnsiString( &unixSource ); NtClose( file );
RtlFreeAnsiString( &unixDest );
err: err:
RtlFreeUnicodeString( &ntSource ); RtlFreeUnicodeString( &ntSource );
RtlFreeUnicodeString( &ntDest ); RtlFreeUnicodeString( &ntDest );
HeapFree( GetProcessHeap(), 0, info );
return ret; return ret;
} }
......
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