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