added support for template directories (copy ntfs extended attributes)
to CreateDirectoryEx()
Modified: trunk/reactos/lib/kernel32/file/create.c
Modified: trunk/reactos/lib/kernel32/file/dir.c
_____
Modified: trunk/reactos/lib/kernel32/file/create.c
--- trunk/reactos/lib/kernel32/file/create.c 2005-03-20 19:11:52 UTC
(rev 14232)
+++ trunk/reactos/lib/kernel32/file/create.c 2005-03-20 20:27:56 UTC
(rev 14233)
@@ -34,15 +34,26 @@
DWORD
dwFlagsAndAttributes,
HANDLE hTemplateFile)
{
- PWCHAR FileNameW;
+ UNICODE_STRING FileNameU;
+ ANSI_STRING FileName;
HANDLE FileHandle;
DPRINT("CreateFileA(lpFileName %s)\n",lpFileName);
+
+ RtlInitAnsiString (&FileName,
+ (LPSTR)lpFileName);
+
+ /* convert ansi (or oem) string to unicode */
+ if (bIsFileApiAnsi)
+ RtlAnsiStringToUnicodeString (&FileNameU,
+ &FileName,
+ TRUE);
+ else
+ RtlOemStringToUnicodeString (&FileNameU,
+ &FileName,
+ TRUE);
- if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
- return INVALID_HANDLE_VALUE;
-
- FileHandle = CreateFileW (FileNameW ,
+ FileHandle = CreateFileW (FileNameU.Buffer,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
@@ -50,6 +61,10 @@
dwFlagsAndAttributes,
hTemplateFile);
+ RtlFreeHeap (RtlGetProcessHeap (),
+ 0,
+ FileNameU.Buffer);
+
return FileHandle;
}
@@ -254,6 +269,7 @@
{
/* we successfully read the extended attributes, break
the loop
and continue */
+ EaLength = EaInformation.EaSize;
break;
}
else
_____
Modified: trunk/reactos/lib/kernel32/file/dir.c
--- trunk/reactos/lib/kernel32/file/dir.c 2005-03-20 19:11:52 UTC
(rev 14232)
+++ trunk/reactos/lib/kernel32/file/dir.c 2005-03-20 20:27:56 UTC
(rev 14233)
@@ -34,9 +34,13 @@
LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
{
- return CreateDirectoryExA (NULL,
- lpPathName,
- lpSecurityAttributes);
+ PWCHAR PathNameW;
+
+ if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
+ return FALSE;
+
+ return CreateDirectoryW (PathNameW,
+ lpSecurityAttributes);
}
@@ -50,25 +54,28 @@
LPCSTR lpNewDirectory,
LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
- PWCHAR TemplateDirectoryW = NULL;
- PWCHAR NewDirectoryW = NULL;
+ PWCHAR TemplateDirectoryW;
+ PWCHAR NewDirectoryW;
BOOL ret;
- if (lpTemplateDirectory != NULL &&
- !(TemplateDirectoryW = FilenameA2W(lpTemplateDirectory, FALSE)))
+ if (!(TemplateDirectoryW = FilenameA2W(lpTemplateDirectory, TRUE)))
return FALSE;
- if (!(NewDirectoryW = FilenameA2W(lpNewDirectory, TRUE)))
+ if (!(NewDirectoryW = FilenameA2W(lpNewDirectory, FALSE)))
+ {
+ RtlFreeHeap (RtlGetProcessHeap (),
+ 0,
+ TemplateDirectoryW);
return FALSE;
+ }
ret = CreateDirectoryExW (TemplateDirectoryW,
- NewDirectoryW,
- lpSecurityAttributes);
+ NewDirectoryW,
+ lpSecurityAttributes);
- if (lpNewDirectory != NULL)
- RtlFreeHeap (RtlGetProcessHeap (),
- 0,
- NewDirectoryW);
+ RtlFreeHeap (RtlGetProcessHeap (),
+ 0,
+ TemplateDirectoryW);
return ret;
}
@@ -84,9 +91,55 @@
LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
{
- return CreateDirectoryExW (NULL,
- lpPathName,
- lpSecurityAttributes);
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING NtPathU;
+ HANDLE DirectoryHandle;
+ NTSTATUS Status;
+
+ DPRINT ("lpPathName %S lpSecurityAttributes %p\n",
+ lpPathName, lpSecurityAttributes);
+
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpPathName,
+ &NtPathU,
+ NULL,
+ NULL))
+ {
+ SetLastError(ERROR_PATH_NOT_FOUND);
+ return FALSE;
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &NtPathU,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ (lpSecurityAttributes ?
lpSecurityAttributes->lpSecurityDescriptor : NULL));
+
+ Status = NtCreateFile (&DirectoryHandle,
+ GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_CREATE,
+ FILE_DIRECTORY_FILE |
FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+
+ RtlFreeHeap (RtlGetProcessHeap (),
+ 0,
+ NtPathU.Buffer);
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ NtClose (DirectoryHandle);
+
+ return TRUE;
}
@@ -103,55 +156,179 @@
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
- UNICODE_STRING NtPathU;
- HANDLE DirectoryHandle;
+ UNICODE_STRING NtPathU, NtTemplatePathU;
+ HANDLE DirectoryHandle, TemplateHandle;
+ FILE_EA_INFORMATION EaInformation;
NTSTATUS Status;
+ PVOID EaBuffer = NULL;
+ ULONG EaLength = 0;
DPRINT ("lpTemplateDirectory %S lpNewDirectory %S
lpSecurityAttributes %p\n",
lpTemplateDirectory, lpNewDirectory,
lpSecurityAttributes);
- // Can't create empty directory
- if(lpNewDirectory == NULL || *lpNewDirectory == 0)
- {
- SetLastError(ERROR_PATH_NOT_FOUND);
- return FALSE;
- }
+ /*
+ * Read the extended attributes from the template directory
+ */
- if (lpTemplateDirectory != NULL && *lpTemplateDirectory != 0)
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpTemplateDirectory,
+ &NtTemplatePathU,
+ NULL,
+ NULL))
{
- // get object attributes from template directory
- DPRINT("KERNEL32:FIXME:%s:%d\n",__FILE__,__LINE__);
+ SetLastError(ERROR_PATH_NOT_FOUND);
return FALSE;
}
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &NtTemplatePathU,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtCreateFile (&TemplateHandle,
+ GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_OPEN,
+ FILE_DIRECTORY_FILE,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap (RtlGetProcessHeap (),
+ 0,
+ NtTemplatePathU.Buffer);
+ SetLastErrorByStatus (Status);
+ return FALSE;
+ }
+
+ for (;;)
+ {
+ Status = NtQueryInformationFile(TemplateHandle,
+ &IoStatusBlock,
+ &EaInformation,
+ sizeof(FILE_EA_INFORMATION),
+ FileEaInformation);
+ if (NT_SUCCESS(Status) && (EaInformation.EaSize != 0))
+ {
+ EaBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ EaInformation.EaSize);
+ if (EaBuffer == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ Status = NtQueryEaFile(TemplateHandle,
+ &IoStatusBlock,
+ EaBuffer,
+ EaInformation.EaSize,
+ FALSE,
+ NULL,
+ 0,
+ NULL,
+ TRUE);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* we successfully read the extended attributes */
+ EaLength = EaInformation.EaSize;
+ break;
+ }
+ else
+ {
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ EaBuffer);
+ EaBuffer = NULL;
+
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ /* unless we just allocated not enough memory, break
the loop
+ and just continue without copying extended
attributes */
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* failure or no extended attributes present, break the
loop */
+ break;
+ }
+ }
+
+ NtClose(TemplateHandle);
+
+ RtlFreeHeap (RtlGetProcessHeap (),
+ 0,
+ NtTemplatePathU.Buffer);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* free the he extended attributes buffer */
+ if (EaBuffer != NULL)
+ {
+ RtlFreeHeap (RtlGetProcessHeap (),
+ 0,
+ EaBuffer);
+ }
+
+ SetLastErrorByStatus (Status);
+ return FALSE;
+ }
+
+ /*
+ * Create the new directory and copy over the extended
attributes if
+ * needed
+ */
+
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpNewDirectory,
&NtPathU,
NULL,
NULL))
+ {
+ /* free the he extended attributes buffer */
+ if (EaBuffer != NULL)
+ {
+ RtlFreeHeap (RtlGetProcessHeap (),
+ 0,
+ EaBuffer);
+ }
+
+ SetLastError(ERROR_PATH_NOT_FOUND);
return FALSE;
+ }
- DPRINT ("NtPathU \'%wZ\'\n", &NtPathU);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &NtPathU,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ (lpSecurityAttributes ?
lpSecurityAttributes->lpSecurityDescriptor : NULL));
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
- ObjectAttributes.ObjectName = &NtPathU;
- ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE |
OBJ_INHERIT;
- ObjectAttributes.SecurityDescriptor = NULL;
- ObjectAttributes.SecurityQualityOfService = NULL;
-
Status = NtCreateFile (&DirectoryHandle,
- DIRECTORY_ALL_ACCESS,
+ GENERIC_READ,
&ObjectAttributes,
&IoStatusBlock,
NULL,
- FILE_ATTRIBUTE_DIRECTORY,
- 0,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_CREATE,
- FILE_DIRECTORY_FILE,
- NULL,
- 0);
- DPRINT("Status: %lx\n", Status);
+ FILE_DIRECTORY_FILE |
FILE_SYNCHRONOUS_IO_NONALERT,
+ EaBuffer,
+ EaLength);
+ /* free the he extended attributes buffer */
+ if (EaBuffer != NULL)
+ {
+ RtlFreeHeap (RtlGetProcessHeap (),
+ 0,
+ EaBuffer);
+ }
+
RtlFreeHeap (RtlGetProcessHeap (),
0,
NtPathU.Buffer);
@@ -212,12 +389,11 @@
NULL))
return FALSE;
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
- ObjectAttributes.ObjectName = &NtPathU;
- ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE|
OBJ_INHERIT;
- ObjectAttributes.SecurityDescriptor = NULL;
- ObjectAttributes.SecurityQualityOfService = NULL;
+ InitializeObjectAttributes(&ObjectAttributes,
+ &NtPathU,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
DPRINT("NtPathU '%S'\n", NtPathU.Buffer);
@@ -251,22 +427,14 @@
&FileDispInfo,
sizeof(FILE_DISPOSITION_INFORMATION),
FileDispositionInformation);
+ NtClose(DirectoryHandle);
+
if (!NT_SUCCESS(Status))
{
- CHECKPOINT;
- NtClose(DirectoryHandle);
SetLastErrorByStatus (Status);
return FALSE;
}
- Status = NtClose (DirectoryHandle);
- if (!NT_SUCCESS(Status))
- {
- CHECKPOINT;
- SetLastErrorByStatus (Status);
- return FALSE;
- }
-
return TRUE;
}