[ros-dev] [ros-diffs] [pschweitzer] 53823: [KERNEL32] Simplify overcomplicated function CreateHardlinkW(), and SEHify it.
Alex Ionescu
ionucu at videotron.ca
Sat Sep 24 12:36:27 UTC 2011
Why are you putting SEH everywhere??? Just to avoid goto? This is infinitely
retarded. Exceptions should not be used as a mechanism for flow control.
Best regards,
Alex Ionescu
On Sat, Sep 24, 2011 at 3:51 AM, <pschweitzer at svn.reactos.org> wrote:
> 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/file/hardlink.c?rev=53823&r1=53822&r2=53823&view=diff
>
> ==============================================================================
> --- 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 at users.sourceforge.net)
> - * UPDATE HISTORY:
> - * Created 13/03/2004
> + * Pierre Schweitzer (pierre.schweitzer at 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 */
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.reactos.org/pipermail/ros-dev/attachments/20110924/1b338e50/attachment-0001.htm>
More information about the Ros-dev
mailing list