3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/dir.c
6 * PURPOSE: Directory functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
13 * NOTES: Changed to using ZwCreateFile
16 /* INCLUDES ******************************************************************/
21 #include <kernel32/kernel32.h>
24 /* FUNCTIONS *****************************************************************/
33 LPSECURITY_ATTRIBUTES lpSecurityAttributes
36 return CreateDirectoryExA (NULL,
38 lpSecurityAttributes);
48 LPCSTR lpTemplateDirectory,
49 LPCSTR lpNewDirectory,
50 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
52 UNICODE_STRING TmplDirU;
53 UNICODE_STRING NewDirU;
58 RtlInitUnicodeString (&TmplDirU,
61 RtlInitUnicodeString (&NewDirU,
64 if (lpTemplateDirectory != NULL)
66 RtlInitAnsiString (&TmplDir,
67 (LPSTR)lpTemplateDirectory);
69 /* convert ansi (or oem) string to unicode */
71 RtlAnsiStringToUnicodeString (&TmplDirU,
75 RtlOemStringToUnicodeString (&TmplDirU,
80 if (lpNewDirectory != NULL)
82 RtlInitAnsiString (&NewDir,
83 (LPSTR)lpNewDirectory);
85 /* convert ansi (or oem) string to unicode */
87 RtlAnsiStringToUnicodeString (&NewDirU,
91 RtlOemStringToUnicodeString (&NewDirU,
96 Result = CreateDirectoryExW (TmplDirU.Buffer,
98 lpSecurityAttributes);
100 if (lpTemplateDirectory != NULL)
101 RtlFreeHeap (RtlGetProcessHeap (),
105 if (lpNewDirectory != NULL)
106 RtlFreeHeap (RtlGetProcessHeap (),
121 LPSECURITY_ATTRIBUTES lpSecurityAttributes
124 return CreateDirectoryExW (NULL,
126 lpSecurityAttributes);
136 LPCWSTR lpTemplateDirectory,
137 LPCWSTR lpNewDirectory,
138 LPSECURITY_ATTRIBUTES lpSecurityAttributes
141 OBJECT_ATTRIBUTES ObjectAttributes;
142 IO_STATUS_BLOCK IoStatusBlock;
143 UNICODE_STRING NtPathU;
144 HANDLE DirectoryHandle;
147 DPRINT ("lpTemplateDirectory %S lpNewDirectory %S lpSecurityAttributes %p\n",
148 lpTemplateDirectory, lpNewDirectory, lpSecurityAttributes);
150 // Can't create empty directory
151 if(lpNewDirectory == NULL || *lpNewDirectory == 0)
153 SetLastError(ERROR_PATH_NOT_FOUND);
157 if (lpTemplateDirectory != NULL && *lpTemplateDirectory != 0)
159 // get object attributes from template directory
160 DPRINT("KERNEL32:FIXME:%s:%d\n",__FILE__,__LINE__);
164 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpNewDirectory,
170 DPRINT1 ("NtPathU \'%wZ\'\n", &NtPathU);
172 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
173 ObjectAttributes.RootDirectory = NULL;
174 ObjectAttributes.ObjectName = &NtPathU;
175 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT;
176 ObjectAttributes.SecurityDescriptor = NULL;
177 ObjectAttributes.SecurityQualityOfService = NULL;
179 Status = NtCreateFile (&DirectoryHandle,
180 DIRECTORY_ALL_ACCESS,
184 FILE_ATTRIBUTE_DIRECTORY,
190 DPRINT("Status: %lx\n", Status);
192 RtlFreeHeap (RtlGetProcessHeap (),
196 if (!NT_SUCCESS(Status))
198 SetLastErrorByStatus(Status);
202 NtClose (DirectoryHandle);
217 UNICODE_STRING PathNameU;
218 ANSI_STRING PathName;
221 RtlInitAnsiString (&PathName,
224 /* convert ansi (or oem) string to unicode */
226 RtlAnsiStringToUnicodeString (&PathNameU,
230 RtlOemStringToUnicodeString (&PathNameU,
234 Result = RemoveDirectoryW (PathNameU.Buffer);
236 RtlFreeHeap (RtlGetProcessHeap (),
253 FILE_DISPOSITION_INFORMATION FileDispInfo;
254 OBJECT_ATTRIBUTES ObjectAttributes;
255 IO_STATUS_BLOCK IoStatusBlock;
256 UNICODE_STRING NtPathU;
257 HANDLE DirectoryHandle;
260 DPRINT("lpPathName %S\n", lpPathName);
262 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpPathName,
268 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
269 ObjectAttributes.RootDirectory = NULL;
270 ObjectAttributes.ObjectName = &NtPathU;
271 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
272 ObjectAttributes.SecurityDescriptor = NULL;
273 ObjectAttributes.SecurityQualityOfService = NULL;
275 DPRINT("NtPathU '%S'\n", NtPathU.Buffer);
277 Status = NtCreateFile (&DirectoryHandle,
278 FILE_WRITE_ATTRIBUTES, /* 0x110080 */
282 FILE_ATTRIBUTE_DIRECTORY, /* 0x7 */
285 FILE_DIRECTORY_FILE, /* 0x204021 */
289 RtlFreeHeap (RtlGetProcessHeap (),
293 if (!NT_SUCCESS(Status))
296 SetLastErrorByStatus (Status);
300 FileDispInfo.DoDeleteFile = TRUE;
302 Status = NtSetInformationFile (DirectoryHandle,
305 sizeof(FILE_DISPOSITION_INFORMATION),
306 FileDispositionInformation);
307 if (!NT_SUCCESS(Status))
310 NtClose(DirectoryHandle);
311 SetLastErrorByStatus (Status);
315 Status = NtClose (DirectoryHandle);
316 if (!NT_SUCCESS(Status))
319 SetLastErrorByStatus (Status);
339 UNICODE_STRING FileNameU;
340 UNICODE_STRING FullNameU;
341 ANSI_STRING FileName;
342 ANSI_STRING FullName;
348 DPRINT("GetFullPathNameA(lpFileName %s, nBufferLength %d, lpBuffer %p, "
349 "lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
351 RtlInitAnsiString (&FileName,
354 RtlAnsiStringToUnicodeString (&FileNameU,
358 BufferLength = nBufferLength * sizeof(WCHAR);
360 FullNameU.MaximumLength = BufferLength;
361 FullNameU.Length = 0;
362 FullNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
366 FullNameU.Length = RtlGetFullPathName_U (FileNameU.Buffer,
371 RtlFreeUnicodeString (&FileNameU);
373 FullName.MaximumLength = nBufferLength;
375 FullName.Buffer = lpBuffer;
377 if (lpBuffer != NULL )
379 RtlUnicodeStringToAnsiString (&FullName,
383 if (lpFilePart != NULL)
385 Offset = (ULONG)(FilePartU - FullNameU.Buffer);
386 *lpFilePart = FullName.Buffer + Offset;
390 FullNameLen = FullNameU.Length / sizeof(WCHAR);
392 RtlFreeHeap (RtlGetProcessHeap (),
396 DPRINT("lpBuffer %s lpFilePart %s Length %ld\n",
397 lpBuffer, lpFilePart, FullName.Length);
417 DPRINT("GetFullPathNameW(lpFileName %S, nBufferLength %d, lpBuffer %p, "
418 "lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
420 Length = RtlGetFullPathName_U ((LPWSTR)lpFileName,
421 nBufferLength * sizeof(WCHAR),
425 DPRINT("lpBuffer %S lpFilePart %S Length %ld\n",
426 lpBuffer, lpFilePart, Length / sizeof(WCHAR));
428 return (Length / sizeof(WCHAR));
443 //1 remove unicode chars and spaces
444 //2 remove preceding and trailing periods.
445 //3 remove embedded periods except the last one
447 //4 Split the string in two parts before and after the period
448 // truncate the part before the period to 6 chars and add ~1
449 // truncate the part after the period to 3 chars
450 //3 Put the new name in uppercase
452 //4 Increment the ~1 string if the resulting name allready exists
464 LPCWSTR lpszLongPath,
465 LPWSTR lpszShortPath,
487 UNICODE_STRING PathU;
488 UNICODE_STRING FileNameU;
489 UNICODE_STRING ExtensionU;
490 UNICODE_STRING BufferU;
492 ANSI_STRING FileName;
493 ANSI_STRING Extension;
498 RtlInitAnsiString (&Path,
500 RtlInitAnsiString (&FileName,
502 RtlInitAnsiString (&Extension,
505 /* convert ansi (or oem) strings to unicode */
508 RtlAnsiStringToUnicodeString (&PathU,
511 RtlAnsiStringToUnicodeString (&FileNameU,
514 RtlAnsiStringToUnicodeString (&ExtensionU,
520 RtlOemStringToUnicodeString (&PathU,
523 RtlOemStringToUnicodeString (&FileNameU,
526 RtlOemStringToUnicodeString (&ExtensionU,
532 BufferU.MaximumLength = nBufferLength * sizeof(WCHAR);
533 BufferU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
535 BufferU.MaximumLength);
538 Buffer.MaximumLength = nBufferLength;
539 Buffer.Buffer = lpBuffer;
541 RetValue = SearchPathW (PathU.Buffer,
548 RtlFreeHeap (RtlGetProcessHeap (),
551 RtlFreeHeap (RtlGetProcessHeap (),
554 RtlFreeHeap (RtlGetProcessHeap (),
558 /* convert ansi (or oem) string to unicode */
560 RtlUnicodeStringToAnsiString (&Buffer,
564 RtlUnicodeStringToOemString (&Buffer,
568 RtlFreeHeap (RtlGetProcessHeap (),
572 *lpFilePart = strrchr (lpBuffer, '\\') + 1;
592 * FUNCTION: Searches for the specified file
594 * lpPath = Points to a null-terminated string that specified the
595 * path to be searched. If this parameters is NULL then
596 * the following directories are searched
597 * The directory from which the application loaded
598 * The current directory
599 * The system directory
600 * The 16-bit system directory
601 * The windows directory
602 * The directories listed in the PATH environment
604 * lpFileName = Specifies the filename to search for
605 * lpExtension = Points to the null-terminated string that specifies
606 * an extension to be added to the filename when
607 * searching for the file. The first character of the
608 * filename extension must be a period (.). The
609 * extension is only added if the specified filename
610 * doesn't end with an extension
612 * If the filename extension is not required or if the
613 * filename contains an extension, this parameters can be
615 * nBufferLength = The length in characters of the buffer for output
616 * lpBuffer = Points to the buffer for the valid path and filename of
618 * lpFilePart = Points to the last component of the valid path and
620 * RETURNS: On success, the length, in characters, of the string copied to the
627 PWCHAR EnvironmentBufferW = NULL;
630 DPRINT("SearchPath\n");
634 len = GetEnvironmentVariableW(L"PATH", &Buffer, 0);
635 len += 1 + GetCurrentDirectoryW(0, &Buffer);
636 len += 1 + GetSystemDirectoryW(&Buffer, 0);
637 len += 1 + GetWindowsDirectoryW(&Buffer, 0);
639 EnvironmentBufferW = (PWCHAR) RtlAllocateHeap(GetProcessHeap(),
640 HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
641 len * sizeof(WCHAR));
642 if (EnvironmentBufferW == NULL)
644 SetLastError(ERROR_OUTOFMEMORY);
648 pos = GetCurrentDirectoryW(len, EnvironmentBufferW);
649 EnvironmentBufferW[pos++] = L';';
650 EnvironmentBufferW[pos] = 0;
651 pos += GetSystemDirectoryW(&EnvironmentBufferW[pos], len - pos);
652 EnvironmentBufferW[pos++] = L';';
653 EnvironmentBufferW[pos] = 0;
654 pos += GetWindowsDirectoryW(&EnvironmentBufferW[pos], len - pos);
655 EnvironmentBufferW[pos++] = L';';
656 EnvironmentBufferW[pos] = 0;
657 pos += GetEnvironmentVariableW(L"PATH", &EnvironmentBufferW[pos], len - pos);
658 lpPath = EnvironmentBufferW;
661 retCode = RtlDosSearchPath_U ((PWCHAR)lpPath, (PWCHAR)lpFileName, (PWCHAR)lpExtension,
662 nBufferLength * sizeof(WCHAR), lpBuffer, lpFilePart);
664 if (EnvironmentBufferW != NULL)
666 RtlFreeHeap(GetProcessHeap(), 0, EnvironmentBufferW);
670 SetLastError(ERROR_FILE_NOT_FOUND);
672 return retCode / sizeof(WCHAR);