implemented CreateSymbolicLink() (not tested/verified yet!)
Modified: trunk/reactos/lib/kernel32/file/create.c
Modified: trunk/reactos/w32api/include/winbase.h

Modified: trunk/reactos/lib/kernel32/file/create.c
--- trunk/reactos/lib/kernel32/file/create.c	2005-08-26 13:06:24 UTC (rev 17558)
+++ trunk/reactos/lib/kernel32/file/create.c	2005-08-26 13:47:56 UTC (rev 17559)
@@ -359,15 +359,109 @@
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL STDCALL
 CreateSymbolicLinkW(IN LPCWSTR lpSymlinkFileName,
                     IN LPCWSTR lpTargetFileName,
                     IN DWORD dwFlags)
 {
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    UNICODE_STRING NtSymLink, NtTargetName;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE hTarget, hSymbolicLink;
+    NTSTATUS Status;
+    BOOL Ret = FALSE;
+    
+    if(!lpSymlinkFileName || !lpTargetFileName)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    
+    if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpSymlinkFileName,
+                                      &NtSymLink,
+                                      NULL,
+                                      NULL))
+    {
+        /* FIXME - right error code? */
+        SetLastError(ERROR_PATH_NOT_FOUND);
+        return FALSE;
+    }
+    
+    if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpTargetFileName,
+                                      &NtTargetName,
+                                      NULL,
+                                      NULL))
+    {
+        /* FIXME - right error code? */
+        SetLastError(ERROR_PATH_NOT_FOUND);
+        goto Cleanup2;
+    }
+    
+    /*
+     * Try to open the target
+     */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &NtTargetName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    
+    if (dwFlags == SYMLINK_FLAG_DIRECTORY)
+    {
+        Status = NtOpenDirectoryObject(&hTarget,
+                                       SYNCHRONIZE,
+                                       &ObjectAttributes);
+    }
+    else
+    {
+        IO_STATUS_BLOCK IoStatusBlock;
+        
+        Status = NtOpenFile(&hTarget,
+                            SYNCHRONIZE,
+                            &ObjectAttributes,
+                            &IoStatusBlock,
+                            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                            FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT);
+    }
+    
+    if (!NT_SUCCESS(Status))
+    {
+        SetLastErrorByStatus(Status);
+        goto Cleanup;
+    }
+
+    NtClose(hTarget);
+    
+    /*
+     * Create the symbolic link
+     */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &NtSymLink,
+                               OBJ_PERMANENT,
+                               NULL,
+                               NULL);
+
+    Status = NtCreateSymbolicLinkObject(&hSymbolicLink,
+                                        SYMBOLIC_LINK_ALL_ACCESS,
+                                        &ObjectAttributes,
+                                        &NtTargetName);
+    if (NT_SUCCESS(Status))
+    {
+        NtClose(hSymbolicLink);
+        Ret = TRUE;
+    }
+    else
+    {
+        SetLastErrorByStatus(Status);
+    }
+
+Cleanup:
+    RtlFreeUnicodeString(&NtTargetName);
+Cleanup2:
+    RtlFreeUnicodeString(&NtSymLink);
+
+    return Ret;
 }
 
 

Modified: trunk/reactos/w32api/include/winbase.h
--- trunk/reactos/w32api/include/winbase.h	2005-08-26 13:06:24 UTC (rev 17558)
+++ trunk/reactos/w32api/include/winbase.h	2005-08-26 13:47:56 UTC (rev 17559)
@@ -504,6 +504,9 @@
 #define QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX 0x00000004
 #define QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE 0x00000008
 #define QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS 0x00000010
+#if (_WIN32_WINNT >= 0x0600)
+#define SYMLINK_FLAG_DIRECTORY 0x1
+#endif
 #endif /* (_WIN32_WINNT >= 0x0501) */
 #if (_WIN32_WINNT >= 0x0500)
 #define REPLACEFILE_WRITE_THROUGH 0x00000001