--- 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;
}
--- 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