reactos/include/ddk
diff -u -r1.13 -r1.14
--- fstypes.h 14 Aug 2003 18:30:27 -0000 1.13
+++ fstypes.h 14 Mar 2004 09:21:41 -0000 1.14
@@ -1,6 +1,6 @@
#ifndef __INCLUDE_DDK_FSTYPES_H
#define __INCLUDE_DDK_FSTYPES_H
-/* $Id: fstypes.h,v 1.13 2003/08/14 18:30:27 silverblade Exp $ */
+/* $Id: fstypes.h,v 1.14 2004/03/14 09:21:41 weiden Exp $ */
#ifndef __USE_W32API
@@ -14,6 +14,12 @@
LARGE_INTEGER EndingByte;
} FILE_LOCK_INFO, *PFILE_LOCK_INFO;
+typedef struct _FILE_LINK_INFORMATION {
+ BOOLEAN ReplaceIfExists;
+ HANDLE RootDirectory;
+ ULONG FileNameLength;
+ WCHAR FileName[1];
+} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;
typedef NTSTATUS (*PCOMPLETE_LOCK_IRP_ROUTINE) (
IN PVOID Context,
reactos/lib/kernel32
diff -u -r1.77 -r1.78
--- makefile 22 Feb 2004 17:30:32 -0000 1.77
+++ makefile 14 Mar 2004 09:21:41 -0000 1.78
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.77 2004/02/22 17:30:32 chorns Exp $
+# $Id: makefile,v 1.78 2004/03/14 09:21:41 weiden Exp $
PATH_TO_TOP = ../..
@@ -41,7 +41,7 @@
file/create.o file/find.o file/copy.o file/pipe.o \
file/move.o file/lock.o file/rw.o file/delete.o \
file/npipe.o file/tape.o file/mailslot.o file/backup.o \
- file/cnotify.o
+ file/cnotify.o file/hardlink.o
MEM_OBJECTS = mem/global.o mem/heap.o mem/isbad.o mem/local.o \
mem/procmem.o mem/section.o mem/virtual.o
reactos/lib/kernel32/misc
diff -u -r1.62 -r1.63
--- stubs.c 15 Feb 2004 07:03:56 -0000 1.62
+++ stubs.c 14 Mar 2004 09:21:41 -0000 1.63
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.62 2004/02/15 07:03:56 arty Exp $
+/* $Id: stubs.c,v 1.63 2004/03/14 09:21:41 weiden Exp $
*
* KERNEL32.DLL stubs (unimplemented functions)
* Remove from this file, if you implement them.
@@ -1656,21 +1656,6 @@
/*
* @unimplemented
*/
-BOOL
-STDCALL
-CreateHardLinkW(
- LPCWSTR lpFileName,
- LPCWSTR lpExistingFileName,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes
- )
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/*
- * @unimplemented
- */
HANDLE
STDCALL
CreateJobObjectW(
@@ -2045,21 +2030,6 @@
/*
* @unimplemented
*/
-BOOL
-STDCALL
-CreateHardLinkA(
- LPCSTR lpFileName,
- LPCSTR lpExistingFileName,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes
- )
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/*
- * @unimplemented
- */
HANDLE
STDCALL
CreateJobObjectA(
reactos/lib/kernel32/file
diff -N hardlink.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ hardlink.c 14 Mar 2004 09:21:42 -0000 1.1
@@ -0,0 +1,251 @@
+/* $Id: hardlink.c,v 1.1 2004/03/14 09:21:42 weiden Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/kernel32/file/hardlink.c
+ * PURPOSE: Hardlink functions
+ * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * Created 13/03/2004
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <k32.h>
+#include <ddk/ntifs.h>
+
+#define NDEBUG
+#include "../include/debug.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+CreateHardLinkW(
+ LPCWSTR lpFileName,
+ LPCWSTR lpExistingFileName,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes
+)
+{
+ UNICODE_STRING LinkTarget, LinkName, CheckDrive, LinkDrive, LanManager;
+ LPWSTR lpNtLinkTarget, lpFilePart;
+ ULONG NeededSize;
+ LPVOID lpSecurityDescriptor;
+ WCHAR wCheckDrive[10];
+ OBJECT_ATTRIBUTES ObjectAttribues;
+ PFILE_LINK_INFORMATION LinkInformation;
+ IO_STATUS_BLOCK IoStatus;
+ HANDLE hFile, hTarget;
+ NTSTATUS Status;
+
+ if(!lpFileName || !lpExistingFileName)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ lpSecurityDescriptor = (lpSecurityAttributes ? lpSecurityAttributes->lpSecurityDescriptor : NULL);
+
+ if(RtlDetermineDosPathNameType_U((LPWSTR)lpFileName) == 1 ||
+ RtlDetermineDosPathNameType_U((LPWSTR)lpExistingFileName) == 1)
+ {
+ DPRINT1("CreateHardLinkW() cannot handle UNC Paths!\n");
+ SetLastError(ERROR_INVALID_NAME);
+ return FALSE;
+ }
+
+ if(!RtlDosPathNameToNtPathName_U((LPWSTR)lpExistingFileName, &LinkTarget, NULL, NULL))
+ {
+ SetLastError(ERROR_PATH_NOT_FOUND);
+ return FALSE;
+ }
+
+ if(!(NeededSize = RtlGetFullPathName_U((LPWSTR)lpExistingFileName, 0, NULL, NULL)))
+ {
+ RtlFreeUnicodeString(&LinkTarget);
+ SetLastError(ERROR_INVALID_NAME);
+ 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))
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
+ RtlFreeUnicodeString(&LinkTarget);
+ SetLastError(ERROR_INVALID_NAME);
+ return FALSE;
+ }
+
+ swprintf(wCheckDrive, L"\\??\\%c:", (WCHAR)(*lpNtLinkTarget));
+ RtlInitUnicodeString(&CheckDrive, wCheckDrive);
+
+ 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,
+ &CheckDrive,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = ZwOpenSymbolicLinkObject(&hFile, 1, &ObjectAttribues);
+ if(!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, LinkDrive.Buffer);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
+ RtlFreeUnicodeString(&LinkTarget);
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ RtlInitUnicodeString(&LanManager, L"\\Device\\LanmanRedirector\\");
+
+ ZwQuerySymbolicLinkObject(hFile, &LinkDrive, NULL);
+
+ if(RtlPrefixUnicodeString(&LanManager, &LinkDrive, TRUE))
+ {
+ ZwClose(hFile);
+ 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,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ lpSecurityDescriptor);
+
+ Status = ZwOpenFile(&hTarget, SYNCHRONIZE | DELETE, &ObjectAttribues, &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))
+ {
+ ZwClose(hFile);
+ 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);
+ if(!(LinkInformation = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize)))
+ {
+ 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->RootDirectory = 0;
+ LinkInformation->FileNameLength = LinkName.Length;
+ RtlCopyMemory(LinkInformation->FileName, LinkName.Buffer, LinkName.Length);
+
+ Status = ZwSetInformationFile(hTarget, &IoStatus, LinkInformation, NeededSize, FileLinkInformation);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ }
+
+ ZwClose(hTarget);
+ ZwClose(hFile);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, LinkInformation);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, LinkDrive.Buffer);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, lpNtLinkTarget);
+ RtlFreeUnicodeString(&LinkTarget);
+ return NT_SUCCESS(Status);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+CreateHardLinkA(
+ LPCSTR lpFileName,
+ LPCSTR lpExistingFileName,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes
+)
+{
+ ANSI_STRING FileNameA, ExistingFileNameA;
+ UNICODE_STRING FileName, ExistingFileName;
+ NTSTATUS Status;
+ BOOL Ret;
+
+ if(!lpFileName || !lpExistingFileName)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ RtlInitAnsiString(&FileNameA, (LPSTR)lpFileName);
+ RtlInitAnsiString(&ExistingFileNameA, (LPSTR)lpExistingFileName);
+
+ if(bIsFileApiAnsi)
+ Status = RtlAnsiStringToUnicodeString(&FileName, &FileNameA, TRUE);
+ else
+ Status = RtlOemStringToUnicodeString(&FileName, &FileNameA, TRUE);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ if(bIsFileApiAnsi)
+ Status = RtlAnsiStringToUnicodeString(&ExistingFileName, &ExistingFileNameA, TRUE);
+ else
+ Status = RtlOemStringToUnicodeString(&ExistingFileName, &ExistingFileNameA, TRUE);
+ if(!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&FileName);
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ Ret = CreateHardLinkW(FileName.Buffer, ExistingFileName.Buffer, lpSecurityAttributes);
+
+ RtlFreeUnicodeString(&FileName);
+ RtlFreeUnicodeString(&ExistingFileName);
+
+ return Ret;
+}
+
+/* EOF */