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/f... ============================================================================== --- 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@users.sourceforge.net) - * UPDATE HISTORY: - * Created 13/03/2004 + * Pierre Schweitzer (pierre.schweitzer@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 */