Author: pschweitzer
Date: Sat Sep 24 07:51:21 2011
New Revision: 53823
URL:
http://svn.reactos.org/svn/reactos?rev=53823&view=rev
Log:
[KERNEL32]
Simplify overcomplicated function CreateHardlinkW(), and SEHify it.
Modified:
trunk/reactos/dll/win32/kernel32/client/file/hardlink.c
Modified: trunk/reactos/dll/win32/kernel32/client/file/hardlink.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/file/hardlink.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/file/hardlink.c [iso-8859-1] Sat Sep 24
07:51:21 2011
@@ -2,11 +2,10 @@
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
- * FILE: lib/kernel32/file/hardlink.c
+ * FILE: dll/win32/kernel32/client/file/hardlink.c
* PURPOSE: Hardlink functions
* PROGRAMMER: Thomas Weidenmueller (w3seek(a)users.sourceforge.net)
- * UPDATE HISTORY:
- * Created 13/03/2004
+ * Pierre Schweitzer (pierre.schweitzer(a)reactos.org)
*/
/* INCLUDES *****************************************************************/
@@ -27,169 +26,110 @@
LPCWSTR lpExistingFileName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
- UNICODE_STRING LinkTarget, LinkName;
- LPVOID lpSecurityDescriptor;
- PFILE_LINK_INFORMATION LinkInformation;
- IO_STATUS_BLOCK IoStatus;
- NTSTATUS Status;
- BOOL Ret = FALSE;
+ NTSTATUS Status;
+ BOOL Ret = FALSE;
+ ULONG NeededSize;
+ IO_STATUS_BLOCK IoStatusBlock;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hTarget = INVALID_HANDLE_VALUE;
+ PFILE_LINK_INFORMATION LinkInformation = NULL;
+ UNICODE_STRING LinkTarget = {0, 0, NULL}, LinkName = {0, 0, NULL};
- if(!lpFileName || !lpExistingFileName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
+ TRACE("CreateHardLinkW: %S, %S, %p\n", lpFileName, lpExistingFileName,
lpSecurityAttributes);
- lpSecurityDescriptor = (lpSecurityAttributes ?
lpSecurityAttributes->lpSecurityDescriptor : NULL);
+ /* Validate parameters */
+ if(!lpFileName || !lpExistingFileName)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
- if(RtlDetermineDosPathNameType_U((LPWSTR)lpFileName) == 1 ||
- RtlDetermineDosPathNameType_U((LPWSTR)lpExistingFileName) == 1)
- {
- WARN("CreateHardLinkW() cannot handle UNC Paths!\n");
- SetLastError(ERROR_INVALID_NAME);
- return FALSE;
- }
+ _SEH2_TRY
+ {
+ /* Get target UNC path */
+ if (!RtlDosPathNameToNtPathName_U(lpExistingFileName, &LinkTarget, NULL,
NULL))
+ {
+ SetLastError(ERROR_PATH_NOT_FOUND);
+ _SEH2_LEAVE;
+ }
- if(RtlDosPathNameToNtPathName_U(lpExistingFileName, &LinkTarget, NULL, NULL))
- {
- ULONG NeededSize = RtlGetFullPathName_U((LPWSTR)lpExistingFileName, 0, NULL, NULL);
- if(NeededSize > 0)
+ /* Open target */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkTarget,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ (lpSecurityAttributes ?
lpSecurityAttributes->lpSecurityDescriptor : NULL));
+
+ Status = NtOpenFile(&hTarget,
+ SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ _SEH2_LEAVE;
+ }
+
+ /* Get UNC path name for link */
+ if (!RtlDosPathNameToNtPathName_U(lpFileName, &LinkName, NULL, NULL))
+ {
+ SetLastError(ERROR_PATH_NOT_FOUND);
+ _SEH2_LEAVE;
+ }
+
+ /* Prepare data for link */
+ NeededSize = sizeof(FILE_LINK_INFORMATION) + LinkName.Length;
+ LinkInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, NeededSize);
+ if (!LinkInformation)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ _SEH2_LEAVE;
+ }
+
+ RtlMoveMemory(LinkInformation->FileName, LinkName.Buffer, LinkName.Length);
+ LinkInformation->ReplaceIfExists = FALSE;
+ LinkInformation->RootDirectory = 0;
+ LinkInformation->FileNameLength = LinkName.Length;
+
+ /* Create hard link */
+ Status = NtSetInformationFile(hTarget,
+ &IoStatusBlock,
+ LinkInformation,
+ NeededSize,
+ FileLinkInformation);
+ if (NT_SUCCESS(Status))
+ {
+ Ret = TRUE;
+ }
+ }
+ _SEH2_FINALLY
{
- LPWSTR lpNtLinkTarget = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
NeededSize * sizeof(WCHAR));
- if(lpNtLinkTarget != NULL)
- {
- LPWSTR lpFilePart;
+ if (LinkTarget.Buffer)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, LinkTarget.Buffer);
+ }
- if(RtlGetFullPathName_U((LPWSTR)lpExistingFileName, NeededSize, lpNtLinkTarget,
&lpFilePart) &&
- (*lpNtLinkTarget) != L'\0')
+ if (hTarget != INVALID_HANDLE_VALUE)
{
- UNICODE_STRING CheckDrive, LinkDrive;
- WCHAR wCheckDrive[10];
+ NtClose(hTarget);
+ }
- swprintf(wCheckDrive, L"\\??\\%c:", (WCHAR)(*lpNtLinkTarget));
- RtlInitUnicodeString(&CheckDrive, wCheckDrive);
+ if (LinkName.Buffer)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, LinkName.Buffer);
+ }
- RtlZeroMemory(&LinkDrive, sizeof(UNICODE_STRING));
+ if (LinkInformation)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, LinkInformation);
+ }
+ }
+ _SEH2_END;
- LinkDrive.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
(MAX_PATH + 1) * sizeof(WCHAR));
- if(LinkDrive.Buffer != NULL)
- {
- HANDLE hFile, hTarget;
- OBJECT_ATTRIBUTES ObjectAttributes;
-
- InitializeObjectAttributes(&ObjectAttributes,
- &CheckDrive,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- Status = NtOpenSymbolicLinkObject(&hFile, 1, &ObjectAttributes);
- if(NT_SUCCESS(Status))
- {
- UNICODE_STRING LanManager;
-
- RtlInitUnicodeString(&LanManager,
L"\\Device\\LanmanRedirector\\");
-
- NtQuerySymbolicLinkObject(hFile, &LinkDrive, NULL);
-
- if(!RtlPrefixUnicodeString(&LanManager, &LinkDrive, TRUE))
- {
- InitializeObjectAttributes(&ObjectAttributes,
- &LinkTarget,
- OBJ_CASE_INSENSITIVE,
- NULL,
- lpSecurityDescriptor);
- Status = NtOpenFile(&hTarget,
- SYNCHRONIZE | DELETE,
- &ObjectAttributes,
- &IoStatus,
- FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE,
- FILE_SYNCHRONOUS_IO_NONALERT |
FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
- if(NT_SUCCESS(Status))
- {
- if(RtlDosPathNameToNtPathName_U(lpFileName, &LinkName, NULL,
NULL))
- {
- NeededSize = sizeof(FILE_LINK_INFORMATION) + LinkName.Length +
sizeof(WCHAR);
- LinkInformation = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY, NeededSize);
- if(LinkInformation != NULL)
- {
- LinkInformation->ReplaceIfExists = FALSE;
- LinkInformation->RootDirectory = 0;
- LinkInformation->FileNameLength = LinkName.Length;
- RtlCopyMemory(LinkInformation->FileName, LinkName.Buffer,
LinkName.Length);
-
- Status = NtSetInformationFile(hTarget, &IoStatus,
LinkInformation, NeededSize, FileLinkInformation);
- if(NT_SUCCESS(Status))
- {
- Ret = TRUE;
- }
- else
- {
- BaseSetLastNTError(Status);
- }
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, LinkInformation);
- }
- else
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- }
- }
- else
- {
- SetLastError(ERROR_PATH_NOT_FOUND);
- }
- NtClose(hTarget);
- }
- else
- {
- WARN("Unable to open link destination \"%wZ\"!\n",
&LinkTarget);
- BaseSetLastNTError(Status);
- }
- }
- else
- {
- WARN("Path \"%wZ\" must not be a mapped drive!\n",
&LinkDrive);
- SetLastError(ERROR_INVALID_NAME);
- }
-
- NtClose(hFile);
- }
- else
- {
- BaseSetLastNTError(Status);
- }
- }
- else
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- }
- }
- else
- {
- SetLastError(ERROR_INVALID_NAME);
- }
- RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
- }
- else
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- }
- }
- else
- {
- SetLastError(ERROR_INVALID_NAME);
- }
- RtlFreeHeap(RtlGetProcessHeap(), 0, LinkTarget.Buffer);
- }
- else
- {
- SetLastError(ERROR_PATH_NOT_FOUND);
- }
-
- return Ret;
+ return Ret;
}
-
/*
* @implemented
@@ -199,26 +139,32 @@
LPCSTR lpExistingFileName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
- PWCHAR FileNameW, ExistingFileNameW;
- BOOL Ret;
+ BOOL Ret;
+ PUNICODE_STRING lpFileNameW;
+ UNICODE_STRING ExistingFileNameW;
- if(!lpFileName || !lpExistingFileName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
+ lpFileNameW = Basep8BitStringToStaticUnicodeString(lpFileName);
+ if (!lpFileNameW)
+ {
+ return FALSE;
+ }
- if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
- return FALSE;
+ if (!lpExistingFileName)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
- if (!(ExistingFileNameW = FilenameA2W(lpExistingFileName, TRUE)))
- return FALSE;
+ if (!Basep8BitStringToDynamicUnicodeString(&ExistingFileNameW,
lpExistingFileName))
+ {
+ return FALSE;
+ }
- Ret = CreateHardLinkW(FileNameW , ExistingFileNameW , lpSecurityAttributes);
+ Ret = CreateHardLinkW(lpFileNameW->Buffer, ExistingFileNameW.Buffer,
lpSecurityAttributes);
- RtlFreeHeap(RtlGetProcessHeap(), 0, ExistingFileNameW);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ExistingFileNameW.Buffer);
- return Ret;
+ return Ret;
}
/* EOF */