don't duplicate tons of code for error handling

svn path=/trunk/; revision=11160
This commit is contained in:
Thomas Bluemel 2004-10-02 20:56:54 +00:00
parent 86b4ec40d4
commit 3f75c451d1

View file

@ -1,4 +1,4 @@
/* $Id: hardlink.c,v 1.2 2004/03/14 10:16:18 weiden Exp $ /* $Id: hardlink.c,v 1.3 2004/10/02 20:56:54 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -25,22 +25,16 @@
* @implemented * @implemented
*/ */
BOOL STDCALL BOOL STDCALL
CreateHardLinkW( CreateHardLinkW(LPCWSTR lpFileName,
LPCWSTR lpFileName,
LPCWSTR lpExistingFileName, LPCWSTR lpExistingFileName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes LPSECURITY_ATTRIBUTES lpSecurityAttributes)
)
{ {
UNICODE_STRING LinkTarget, LinkName, CheckDrive, LinkDrive, LanManager; UNICODE_STRING LinkTarget, LinkName;
LPWSTR lpNtLinkTarget, lpFilePart;
ULONG NeededSize;
LPVOID lpSecurityDescriptor; LPVOID lpSecurityDescriptor;
WCHAR wCheckDrive[10];
OBJECT_ATTRIBUTES ObjectAttribues;
PFILE_LINK_INFORMATION LinkInformation; PFILE_LINK_INFORMATION LinkInformation;
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
HANDLE hFile, hTarget;
NTSTATUS Status; NTSTATUS Status;
BOOL Ret = FALSE;
if(!lpFileName || !lpExistingFileName) if(!lpFileName || !lpExistingFileName)
{ {
@ -58,141 +52,144 @@ CreateHardLinkW(
return FALSE; return FALSE;
} }
if(!RtlDosPathNameToNtPathName_U((LPWSTR)lpExistingFileName, &LinkTarget, NULL, NULL)) if(RtlDosPathNameToNtPathName_U((LPWSTR)lpExistingFileName, &LinkTarget, NULL, NULL))
{ {
SetLastError(ERROR_PATH_NOT_FOUND); ULONG NeededSize = RtlGetFullPathName_U((LPWSTR)lpExistingFileName, 0, NULL, NULL);
return FALSE; if(NeededSize > 0)
} {
LPWSTR lpNtLinkTarget = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize * sizeof(WCHAR));
if(lpNtLinkTarget != NULL)
{
LPWSTR lpFilePart;
if(!(NeededSize = RtlGetFullPathName_U((LPWSTR)lpExistingFileName, 0, NULL, NULL))) if(RtlGetFullPathName_U((LPWSTR)lpExistingFileName, NeededSize, lpNtLinkTarget, &lpFilePart) &&
(*lpNtLinkTarget) != L'\0')
{ {
RtlFreeUnicodeString(&LinkTarget); UNICODE_STRING CheckDrive, LinkDrive;
SetLastError(ERROR_INVALID_NAME); WCHAR wCheckDrive[10];
return FALSE;
}
NeededSize += 2;
if(!(lpNtLinkTarget = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize * sizeof(WCHAR))))
{
RtlFreeUnicodeString(&LinkTarget);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
if(!RtlGetFullPathName_U((LPWSTR)lpExistingFileName, NeededSize, lpNtLinkTarget, &lpFilePart) ||
(*lpNtLinkTarget) == L'\0')
{
RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
RtlFreeUnicodeString(&LinkTarget);
SetLastError(ERROR_INVALID_NAME);
return FALSE;
}
swprintf(wCheckDrive, L"\\??\\%c:", (WCHAR)(*lpNtLinkTarget)); swprintf(wCheckDrive, L"\\??\\%c:", (WCHAR)(*lpNtLinkTarget));
RtlInitUnicodeString(&CheckDrive, wCheckDrive); RtlInitUnicodeString(&CheckDrive, wCheckDrive);
RtlZeroMemory(&LinkDrive, sizeof(UNICODE_STRING)); RtlZeroMemory(&LinkDrive, sizeof(UNICODE_STRING));
if(!(LinkDrive.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
(MAX_PATH + 1) * sizeof(WCHAR))))
{
RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
RtlFreeUnicodeString(&LinkTarget);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
InitializeObjectAttributes(&ObjectAttribues, 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, &CheckDrive,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
NULL, NULL,
NULL); NULL);
Status = ZwOpenSymbolicLinkObject(&hFile, 1, &ObjectAttribues); Status = NtOpenSymbolicLinkObject(&hFile, 1, &ObjectAttributes);
if(!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
RtlFreeHeap(RtlGetProcessHeap(), 0, LinkDrive.Buffer); UNICODE_STRING LanManager;
RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
RtlFreeUnicodeString(&LinkTarget);
SetLastErrorByStatus(Status);
return FALSE;
}
RtlInitUnicodeString(&LanManager, L"\\Device\\LanmanRedirector\\"); RtlInitUnicodeString(&LanManager, L"\\Device\\LanmanRedirector\\");
ZwQuerySymbolicLinkObject(hFile, &LinkDrive, NULL); NtQuerySymbolicLinkObject(hFile, &LinkDrive, NULL);
if(RtlPrefixUnicodeString(&LanManager, &LinkDrive, TRUE)) if(!RtlPrefixUnicodeString(&LanManager, &LinkDrive, TRUE))
{ {
ZwClose(hFile); InitializeObjectAttributes(&ObjectAttributes,
RtlFreeHeap(RtlGetProcessHeap(), 0, LinkDrive.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
RtlFreeUnicodeString(&LinkTarget);
DPRINT1("Path \"%wZ\" must not be a mapped drive!\n", &LinkDrive);
SetLastError(ERROR_INVALID_NAME);
return FALSE;
}
InitializeObjectAttributes(&ObjectAttribues,
&LinkTarget, &LinkTarget,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
NULL, NULL,
lpSecurityDescriptor); lpSecurityDescriptor);
Status = NtOpenFile(&hTarget,
Status = ZwOpenFile(&hTarget, SYNCHRONIZE | DELETE, &ObjectAttribues, &IoStatus, SYNCHRONIZE | DELETE,
&ObjectAttributes,
&IoStatus,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT); FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
if(!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
ZwClose(hFile); if(RtlDosPathNameToNtPathName_U((LPWSTR)lpFileName, &LinkName, NULL, NULL))
RtlFreeHeap(RtlGetProcessHeap(), 0, LinkDrive.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
RtlFreeUnicodeString(&LinkTarget);
DPRINT1("Unable to open link destination \"%wZ\"!\n", &LinkTarget);
SetLastError(ERROR_INVALID_NAME);
return FALSE;
}
if(!RtlDosPathNameToNtPathName_U((LPWSTR)lpFileName, &LinkName, NULL, NULL))
{ {
ZwClose(hTarget);
ZwClose(hFile);
RtlFreeHeap(RtlGetProcessHeap(), 0, LinkDrive.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
RtlFreeUnicodeString(&LinkTarget);
SetLastError(ERROR_INVALID_NAME);
return FALSE;
}
NeededSize = sizeof(FILE_LINK_INFORMATION) + LinkName.Length + sizeof(WCHAR); NeededSize = sizeof(FILE_LINK_INFORMATION) + LinkName.Length + sizeof(WCHAR);
if(!(LinkInformation = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize))) LinkInformation = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize);
if(LinkInformation != NULL)
{ {
ZwClose(hTarget);
ZwClose(hFile);
RtlFreeHeap(RtlGetProcessHeap(), 0, LinkDrive.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
RtlFreeUnicodeString(&LinkTarget);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
LinkInformation->ReplaceIfExists = FALSE; LinkInformation->ReplaceIfExists = FALSE;
LinkInformation->RootDirectory = 0; LinkInformation->RootDirectory = 0;
LinkInformation->FileNameLength = LinkName.Length; LinkInformation->FileNameLength = LinkName.Length;
RtlCopyMemory(LinkInformation->FileName, LinkName.Buffer, LinkName.Length); RtlCopyMemory(LinkInformation->FileName, LinkName.Buffer, LinkName.Length);
Status = ZwSetInformationFile(hTarget, &IoStatus, LinkInformation, NeededSize, FileLinkInformation); Status = NtSetInformationFile(hTarget, &IoStatus, LinkInformation, NeededSize, FileLinkInformation);
if(!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{
Ret = TRUE;
}
else
{ {
SetLastErrorByStatus(Status); SetLastErrorByStatus(Status);
} }
ZwClose(hTarget);
ZwClose(hFile);
RtlFreeHeap(RtlGetProcessHeap(), 0, LinkInformation); RtlFreeHeap(RtlGetProcessHeap(), 0, LinkInformation);
RtlFreeHeap(RtlGetProcessHeap(), 0, LinkDrive.Buffer); }
else
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
}
}
else
{
SetLastError(ERROR_PATH_NOT_FOUND);
}
NtClose(hTarget);
}
else
{
DPRINT1("Unable to open link destination \"%wZ\"!\n", &LinkTarget);
SetLastErrorByStatus(Status);
}
}
else
{
DPRINT1("Path \"%wZ\" must not be a mapped drive!\n", &LinkDrive);
SetLastError(ERROR_INVALID_NAME);
}
NtClose(hFile);
}
else
{
SetLastErrorByStatus(Status);
}
}
else
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
}
}
else
{
SetLastError(ERROR_INVALID_NAME);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget); RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
}
else
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
}
}
else
{
SetLastError(ERROR_INVALID_NAME);
}
RtlFreeUnicodeString(&LinkTarget); RtlFreeUnicodeString(&LinkTarget);
return NT_SUCCESS(Status); }
else
{
SetLastError(ERROR_PATH_NOT_FOUND);
}
return Ret;
} }
@ -200,11 +197,9 @@ CreateHardLinkW(
* @implemented * @implemented
*/ */
BOOL STDCALL BOOL STDCALL
CreateHardLinkA( CreateHardLinkA(LPCSTR lpFileName,
LPCSTR lpFileName,
LPCSTR lpExistingFileName, LPCSTR lpExistingFileName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes LPSECURITY_ATTRIBUTES lpSecurityAttributes)
)
{ {
ANSI_STRING FileNameA, ExistingFileNameA; ANSI_STRING FileNameA, ExistingFileNameA;
UNICODE_STRING FileName, ExistingFileName; UNICODE_STRING FileName, ExistingFileName;