Commit in reactos on MAIN
include/ddk/fstypes.h+7-11.13 -> 1.14
           /iodef.h+21.26 -> 1.27
lib/kernel32/k32.h+11.6 -> 1.7
            /makefile+2-21.77 -> 1.78
lib/kernel32/misc/stubs.c+1-311.62 -> 1.63
lib/kernel32/file/hardlink.c+251added 1.1
+264-34
1 added + 5 modified, total 6 files
Implemented CreateHardLink()

reactos/include/ddk
fstypes.h 1.13 -> 1.14
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/include/ddk
iodef.h 1.26 -> 1.27
diff -u -r1.26 -r1.27
--- iodef.h	14 Feb 2004 20:11:12 -0000	1.26
+++ iodef.h	14 Mar 2004 09:21:41 -0000	1.27
@@ -428,6 +428,8 @@
 #define FILE_VALID_MAILSLOT_OPTION_FLAGS        0x00000032
 #define FILE_VALID_SET_FLAGS                    0x00001036
 
+#define FILE_OPEN_REPARSE_POINT                 0x00200000
+
 /*
  * special ByteOffset values
  */

reactos/lib/kernel32
k32.h 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- k32.h	23 Jan 2004 21:16:02 -0000	1.6
+++ k32.h	14 Mar 2004 09:21:41 -0000	1.7
@@ -18,6 +18,7 @@
 #include <napi/i386/segment.h>
 #include <napi/teb.h>
 #include <napi/npipe.h>
+#include <napi/types.h>
 #include <ntos/minmax.h>
 #include <csrss/csrss.h>
 #include <reactos/buildno.h>

reactos/lib/kernel32
makefile 1.77 -> 1.78
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
stubs.c 1.62 -> 1.63
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
hardlink.c added at 1.1
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 */
CVSspam 0.2.8