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 ******************************************************************/
18 #include <ddk/ntddk.h>
19 #include <ntdll/rtl.h>
25 #include <kernel32/kernel32.h>
26 #include <kernel32/error.h>
29 /* FUNCTIONS *****************************************************************/
35 LPSECURITY_ATTRIBUTES lpSecurityAttributes
38 return CreateDirectoryExA (NULL,
40 lpSecurityAttributes);
46 LPCSTR lpTemplateDirectory,
47 LPCSTR lpNewDirectory,
48 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
50 UNICODE_STRING TmplDirU;
51 UNICODE_STRING NewDirU;
56 RtlInitUnicodeString (&TmplDirU,
59 RtlInitUnicodeString (&NewDirU,
62 if (lpTemplateDirectory != NULL)
64 RtlInitAnsiString (&TmplDir,
65 (LPSTR)lpTemplateDirectory);
67 /* convert ansi (or oem) string to unicode */
69 RtlAnsiStringToUnicodeString (&TmplDirU,
73 RtlOemStringToUnicodeString (&TmplDirU,
78 if (lpNewDirectory != NULL)
80 RtlInitAnsiString (&NewDir,
81 (LPSTR)lpNewDirectory);
83 /* convert ansi (or oem) string to unicode */
85 RtlAnsiStringToUnicodeString (&NewDirU,
89 RtlOemStringToUnicodeString (&NewDirU,
94 Result = CreateDirectoryExW (TmplDirU.Buffer,
96 lpSecurityAttributes);
98 if (lpTemplateDirectory != NULL)
99 RtlFreeHeap (RtlGetProcessHeap (),
103 if (lpNewDirectory != NULL)
104 RtlFreeHeap (RtlGetProcessHeap (),
116 LPSECURITY_ATTRIBUTES lpSecurityAttributes
119 return CreateDirectoryExW (NULL,
121 lpSecurityAttributes);
128 LPCWSTR lpTemplateDirectory,
129 LPCWSTR lpNewDirectory,
130 LPSECURITY_ATTRIBUTES lpSecurityAttributes
133 OBJECT_ATTRIBUTES ObjectAttributes;
134 IO_STATUS_BLOCK IoStatusBlock;
135 UNICODE_STRING NtPathU;
136 HANDLE DirectoryHandle;
139 DPRINT ("lpTemplateDirectory %S lpNewDirectory %S lpSecurityAttributes %p\n",
140 lpTemplateDirectory, lpNewDirectory, lpSecurityAttributes);
142 if (lpTemplateDirectory != NULL && *lpTemplateDirectory != 0)
144 // get object attributes from template directory
145 DPRINT("KERNEL32:FIXME:%s:%d\n",__FILE__,__LINE__);
149 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpNewDirectory,
155 DPRINT1 ("NtPathU \'%wZ\'\n", &NtPathU);
157 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
158 ObjectAttributes.RootDirectory = NULL;
159 ObjectAttributes.ObjectName = &NtPathU;
160 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT;
161 ObjectAttributes.SecurityDescriptor = NULL;
162 ObjectAttributes.SecurityQualityOfService = NULL;
164 Status = NtCreateFile (&DirectoryHandle,
165 DIRECTORY_ALL_ACCESS,
169 FILE_ATTRIBUTE_DIRECTORY,
175 DPRINT("Status: %lx\n", Status);
177 RtlFreeHeap (RtlGetProcessHeap (),
181 if (!NT_SUCCESS(Status))
183 SetLastErrorByStatus(Status);
187 NtClose (DirectoryHandle);
199 UNICODE_STRING PathNameU;
200 ANSI_STRING PathName;
203 RtlInitAnsiString (&PathName,
206 /* convert ansi (or oem) string to unicode */
208 RtlAnsiStringToUnicodeString (&PathNameU,
212 RtlOemStringToUnicodeString (&PathNameU,
216 Result = RemoveDirectoryW (PathNameU.Buffer);
218 RtlFreeHeap (RtlGetProcessHeap (),
232 FILE_DISPOSITION_INFORMATION FileDispInfo;
233 OBJECT_ATTRIBUTES ObjectAttributes;
234 IO_STATUS_BLOCK IoStatusBlock;
235 UNICODE_STRING NtPathU;
236 HANDLE DirectoryHandle;
239 DPRINT("lpPathName %S\n", lpPathName);
241 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpPathName,
247 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
248 ObjectAttributes.RootDirectory = NULL;
249 ObjectAttributes.ObjectName = &NtPathU;
250 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
251 ObjectAttributes.SecurityDescriptor = NULL;
252 ObjectAttributes.SecurityQualityOfService = NULL;
254 DPRINT("NtPathU '%S'\n", NtPathU.Buffer);
256 Status = NtCreateFile (&DirectoryHandle,
257 FILE_WRITE_ATTRIBUTES, /* 0x110080 */
261 FILE_ATTRIBUTE_DIRECTORY, /* 0x7 */
264 FILE_DIRECTORY_FILE, /* 0x204021 */
268 RtlFreeHeap (RtlGetProcessHeap (),
272 if (!NT_SUCCESS(Status))
275 SetLastErrorByStatus (Status);
279 FileDispInfo.DoDeleteFile = TRUE;
281 Status = NtSetInformationFile (DirectoryHandle,
284 sizeof(FILE_DISPOSITION_INFORMATION),
285 FileDispositionInformation);
286 if (!NT_SUCCESS(Status))
289 NtClose(DirectoryHandle);
290 SetLastErrorByStatus (Status);
294 Status = NtClose (DirectoryHandle);
295 if (!NT_SUCCESS(Status))
298 SetLastErrorByStatus (Status);
315 UNICODE_STRING FileNameU;
316 UNICODE_STRING FullNameU;
317 ANSI_STRING FileName;
318 ANSI_STRING FullName;
323 DPRINT("GetFullPathNameA(lpFileName %s, nBufferLength %d, lpBuffer %p, "
324 "lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
326 RtlInitAnsiString (&FileName,
329 RtlAnsiStringToUnicodeString (&FileNameU,
333 BufferLength = nBufferLength * sizeof(WCHAR);
335 FullNameU.MaximumLength = BufferLength;
336 FullNameU.Length = 0;
337 FullNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
341 FullNameU.Length = RtlGetFullPathName_U (FileNameU.Buffer,
346 RtlFreeUnicodeString (&FileNameU);
348 FullName.MaximumLength = nBufferLength;
350 FullName.Buffer = lpBuffer;
352 RtlUnicodeStringToAnsiString (&FullName,
356 if (lpFilePart != NULL)
358 Offset = (ULONG)(FilePartU - FullNameU.Buffer);
359 *lpFilePart = FullName.Buffer + Offset;
362 RtlFreeHeap (RtlGetProcessHeap (),
366 DPRINT("lpBuffer %s lpFilePart %s Length %ld\n",
367 lpBuffer, lpFilePart, FullName.Length);
369 return FullName.Length;
384 DPRINT("GetFullPathNameW(lpFileName %S, nBufferLength %d, lpBuffer %p, "
385 "lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
387 Length = RtlGetFullPathName_U ((LPWSTR)lpFileName,
388 nBufferLength * sizeof(WCHAR),
392 DPRINT("lpBuffer %S lpFilePart %S Length %ld\n",
393 lpBuffer, lpFilePart, Length / sizeof(WCHAR));
395 return (Length / sizeof(WCHAR));
407 //1 remove unicode chars and spaces
408 //2 remove preceding and trailing periods.
409 //3 remove embedded periods except the last one
411 //4 Split the string in two parts before and after the period
412 // truncate the part before the period to 6 chars and add ~1
413 // truncate the part after the period to 3 chars
414 //3 Put the new name in uppercase
416 //4 Increment the ~1 string if the resulting name allready exists
425 LPCWSTR lpszLongPath,
426 LPWSTR lpszShortPath,
445 UNICODE_STRING PathU;
446 UNICODE_STRING FileNameU;
447 UNICODE_STRING ExtensionU;
448 UNICODE_STRING BufferU;
450 ANSI_STRING FileName;
451 ANSI_STRING Extension;
456 RtlInitAnsiString (&Path,
458 RtlInitAnsiString (&FileName,
460 RtlInitAnsiString (&Extension,
463 /* convert ansi (or oem) strings to unicode */
466 RtlAnsiStringToUnicodeString (&PathU,
469 RtlAnsiStringToUnicodeString (&FileNameU,
472 RtlAnsiStringToUnicodeString (&ExtensionU,
478 RtlOemStringToUnicodeString (&PathU,
481 RtlOemStringToUnicodeString (&FileNameU,
484 RtlOemStringToUnicodeString (&ExtensionU,
490 BufferU.MaximumLength = nBufferLength * sizeof(WCHAR);
491 BufferU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
493 BufferU.MaximumLength);
496 Buffer.MaximumLength = nBufferLength;
497 Buffer.Buffer = lpBuffer;
499 RetValue = SearchPathW (PathU.Buffer,
506 RtlFreeHeap (RtlGetProcessHeap (),
509 RtlFreeHeap (RtlGetProcessHeap (),
512 RtlFreeHeap (RtlGetProcessHeap (),
516 /* convert ansi (or oem) string to unicode */
518 RtlUnicodeStringToAnsiString (&Buffer,
522 RtlUnicodeStringToOemString (&Buffer,
526 RtlFreeHeap (RtlGetProcessHeap (),
530 *lpFilePart = strrchr (lpBuffer, '\\') + 1;
547 * FUNCTION: Searches for the specified file
549 * lpPath = Points to a null-terminated string that specified the
550 * path to be searched. If this parameters is NULL then
551 * the following directories are searched
552 * The directory from which the application loaded
553 * The current directory
554 * The system directory
555 * The 16-bit system directory
556 * The windows directory
557 * The directories listed in the PATH environment
559 * lpFileName = Specifies the filename to search for
560 * lpExtension = Points to the null-terminated string that specifies
561 * an extension to be added to the filename when
562 * searching for the file. The first character of the
563 * filename extension must be a period (.). The
564 * extension is only added if the specified filename
565 * doesn't end with an extension
567 * If the filename extension is not required or if the
568 * filename contains an extension, this parameters can be
570 * nBufferLength = The length in characters of the buffer for output
571 * lpBuffer = Points to the buffer for the valid path and filename of
573 * lpFilePart = Points to the last component of the valid path and
575 * RETURNS: On success, the length, in characters, of the string copied to the
582 PWCHAR EnvironmentBufferW = NULL;
585 DPRINT("SearchPath\n");
589 len = GetEnvironmentVariableW(L"PATH", &Buffer, 0);
590 len += 1 + GetCurrentDirectoryW(0, &Buffer);
591 len += 1 + GetSystemDirectoryW(&Buffer, 0);
592 len += 1 + GetWindowsDirectoryW(&Buffer, 0);
594 EnvironmentBufferW = (PWCHAR) RtlAllocateHeap(GetProcessHeap(),
595 HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
596 len * sizeof(WCHAR));
597 if (EnvironmentBufferW == NULL)
602 pos = GetCurrentDirectoryW(len, EnvironmentBufferW);
603 EnvironmentBufferW[pos++] = L';';
604 EnvironmentBufferW[pos] = 0;
605 pos += GetSystemDirectoryW(&EnvironmentBufferW[pos], len - pos);
606 EnvironmentBufferW[pos++] = L';';
607 EnvironmentBufferW[pos] = 0;
608 pos += GetWindowsDirectoryW(&EnvironmentBufferW[pos], len - pos);
609 EnvironmentBufferW[pos++] = L';';
610 EnvironmentBufferW[pos] = 0;
611 pos += GetEnvironmentVariableW(L"PATH", &EnvironmentBufferW[pos], len - pos);
612 lpPath = EnvironmentBufferW;
615 retCode = RtlDosSearchPath_U ((PWCHAR)lpPath, (PWCHAR)lpFileName, (PWCHAR)lpExtension, nBufferLength, lpBuffer, lpFilePart);
617 if (EnvironmentBufferW != NULL)
619 RtlFreeHeap(GetProcessHeap(), 0, EnvironmentBufferW);