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 *****************************************************************/
30 LPSECURITY_ATTRIBUTES lpSecurityAttributes
33 return CreateDirectoryExA (NULL,
35 lpSecurityAttributes);
41 LPCSTR lpTemplateDirectory,
42 LPCSTR lpNewDirectory,
43 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
45 UNICODE_STRING TmplDirU;
46 UNICODE_STRING NewDirU;
51 RtlInitUnicodeString (&TmplDirU,
54 RtlInitUnicodeString (&NewDirU,
57 if (lpTemplateDirectory != NULL)
59 RtlInitAnsiString (&TmplDir,
60 (LPSTR)lpTemplateDirectory);
62 /* convert ansi (or oem) string to unicode */
64 RtlAnsiStringToUnicodeString (&TmplDirU,
68 RtlOemStringToUnicodeString (&TmplDirU,
73 if (lpNewDirectory != NULL)
75 RtlInitAnsiString (&NewDir,
76 (LPSTR)lpNewDirectory);
78 /* convert ansi (or oem) string to unicode */
80 RtlAnsiStringToUnicodeString (&NewDirU,
84 RtlOemStringToUnicodeString (&NewDirU,
89 Result = CreateDirectoryExW (TmplDirU.Buffer,
91 lpSecurityAttributes);
93 if (lpTemplateDirectory != NULL)
94 RtlFreeHeap (RtlGetProcessHeap (),
98 if (lpNewDirectory != NULL)
99 RtlFreeHeap (RtlGetProcessHeap (),
111 LPSECURITY_ATTRIBUTES lpSecurityAttributes
114 return CreateDirectoryExW (NULL,
116 lpSecurityAttributes);
123 LPCWSTR lpTemplateDirectory,
124 LPCWSTR lpNewDirectory,
125 LPSECURITY_ATTRIBUTES lpSecurityAttributes
128 OBJECT_ATTRIBUTES ObjectAttributes;
129 IO_STATUS_BLOCK IoStatusBlock;
130 UNICODE_STRING NtPathU;
131 HANDLE DirectoryHandle;
134 DPRINT ("lpTemplateDirectory %S lpNewDirectory %S lpSecurityAttributes %p\n",
135 lpTemplateDirectory, lpNewDirectory, lpSecurityAttributes);
137 // Can't create empty directory
138 if(lpNewDirectory == NULL || *lpNewDirectory == 0)
140 SetLastError(ERROR_PATH_NOT_FOUND);
144 if (lpTemplateDirectory != NULL && *lpTemplateDirectory != 0)
146 // get object attributes from template directory
147 DPRINT("KERNEL32:FIXME:%s:%d\n",__FILE__,__LINE__);
151 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpNewDirectory,
157 DPRINT1 ("NtPathU \'%wZ\'\n", &NtPathU);
159 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
160 ObjectAttributes.RootDirectory = NULL;
161 ObjectAttributes.ObjectName = &NtPathU;
162 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT;
163 ObjectAttributes.SecurityDescriptor = NULL;
164 ObjectAttributes.SecurityQualityOfService = NULL;
166 Status = NtCreateFile (&DirectoryHandle,
167 DIRECTORY_ALL_ACCESS,
171 FILE_ATTRIBUTE_DIRECTORY,
177 DPRINT("Status: %lx\n", Status);
179 RtlFreeHeap (RtlGetProcessHeap (),
183 if (!NT_SUCCESS(Status))
185 SetLastErrorByStatus(Status);
189 NtClose (DirectoryHandle);
201 UNICODE_STRING PathNameU;
202 ANSI_STRING PathName;
205 RtlInitAnsiString (&PathName,
208 /* convert ansi (or oem) string to unicode */
210 RtlAnsiStringToUnicodeString (&PathNameU,
214 RtlOemStringToUnicodeString (&PathNameU,
218 Result = RemoveDirectoryW (PathNameU.Buffer);
220 RtlFreeHeap (RtlGetProcessHeap (),
234 FILE_DISPOSITION_INFORMATION FileDispInfo;
235 OBJECT_ATTRIBUTES ObjectAttributes;
236 IO_STATUS_BLOCK IoStatusBlock;
237 UNICODE_STRING NtPathU;
238 HANDLE DirectoryHandle;
241 DPRINT("lpPathName %S\n", lpPathName);
243 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpPathName,
249 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
250 ObjectAttributes.RootDirectory = NULL;
251 ObjectAttributes.ObjectName = &NtPathU;
252 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
253 ObjectAttributes.SecurityDescriptor = NULL;
254 ObjectAttributes.SecurityQualityOfService = NULL;
256 DPRINT("NtPathU '%S'\n", NtPathU.Buffer);
258 Status = NtCreateFile (&DirectoryHandle,
259 FILE_WRITE_ATTRIBUTES, /* 0x110080 */
263 FILE_ATTRIBUTE_DIRECTORY, /* 0x7 */
266 FILE_DIRECTORY_FILE, /* 0x204021 */
270 RtlFreeHeap (RtlGetProcessHeap (),
274 if (!NT_SUCCESS(Status))
277 SetLastErrorByStatus (Status);
281 FileDispInfo.DoDeleteFile = TRUE;
283 Status = NtSetInformationFile (DirectoryHandle,
286 sizeof(FILE_DISPOSITION_INFORMATION),
287 FileDispositionInformation);
288 if (!NT_SUCCESS(Status))
291 NtClose(DirectoryHandle);
292 SetLastErrorByStatus (Status);
296 Status = NtClose (DirectoryHandle);
297 if (!NT_SUCCESS(Status))
300 SetLastErrorByStatus (Status);
317 UNICODE_STRING FileNameU;
318 UNICODE_STRING FullNameU;
319 ANSI_STRING FileName;
320 ANSI_STRING FullName;
325 DPRINT("GetFullPathNameA(lpFileName %s, nBufferLength %d, lpBuffer %p, "
326 "lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
328 RtlInitAnsiString (&FileName,
331 RtlAnsiStringToUnicodeString (&FileNameU,
335 BufferLength = nBufferLength * sizeof(WCHAR);
337 FullNameU.MaximumLength = BufferLength;
338 FullNameU.Length = 0;
339 FullNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
343 FullNameU.Length = RtlGetFullPathName_U (FileNameU.Buffer,
348 RtlFreeUnicodeString (&FileNameU);
350 FullName.MaximumLength = nBufferLength;
352 FullName.Buffer = lpBuffer;
354 RtlUnicodeStringToAnsiString (&FullName,
358 if (lpFilePart != NULL)
360 Offset = (ULONG)(FilePartU - FullNameU.Buffer);
361 *lpFilePart = FullName.Buffer + Offset;
364 RtlFreeHeap (RtlGetProcessHeap (),
368 DPRINT("lpBuffer %s lpFilePart %s Length %ld\n",
369 lpBuffer, lpFilePart, FullName.Length);
371 return FullName.Length;
386 DPRINT("GetFullPathNameW(lpFileName %S, nBufferLength %d, lpBuffer %p, "
387 "lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
389 Length = RtlGetFullPathName_U ((LPWSTR)lpFileName,
390 nBufferLength * sizeof(WCHAR),
394 DPRINT("lpBuffer %S lpFilePart %S Length %ld\n",
395 lpBuffer, lpFilePart, Length / sizeof(WCHAR));
397 return (Length / sizeof(WCHAR));
409 //1 remove unicode chars and spaces
410 //2 remove preceding and trailing periods.
411 //3 remove embedded periods except the last one
413 //4 Split the string in two parts before and after the period
414 // truncate the part before the period to 6 chars and add ~1
415 // truncate the part after the period to 3 chars
416 //3 Put the new name in uppercase
418 //4 Increment the ~1 string if the resulting name allready exists
427 LPCWSTR lpszLongPath,
428 LPWSTR lpszShortPath,
447 UNICODE_STRING PathU;
448 UNICODE_STRING FileNameU;
449 UNICODE_STRING ExtensionU;
450 UNICODE_STRING BufferU;
452 ANSI_STRING FileName;
453 ANSI_STRING Extension;
458 RtlInitAnsiString (&Path,
460 RtlInitAnsiString (&FileName,
462 RtlInitAnsiString (&Extension,
465 /* convert ansi (or oem) strings to unicode */
468 RtlAnsiStringToUnicodeString (&PathU,
471 RtlAnsiStringToUnicodeString (&FileNameU,
474 RtlAnsiStringToUnicodeString (&ExtensionU,
480 RtlOemStringToUnicodeString (&PathU,
483 RtlOemStringToUnicodeString (&FileNameU,
486 RtlOemStringToUnicodeString (&ExtensionU,
492 BufferU.MaximumLength = nBufferLength * sizeof(WCHAR);
493 BufferU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
495 BufferU.MaximumLength);
498 Buffer.MaximumLength = nBufferLength;
499 Buffer.Buffer = lpBuffer;
501 RetValue = SearchPathW (PathU.Buffer,
508 RtlFreeHeap (RtlGetProcessHeap (),
511 RtlFreeHeap (RtlGetProcessHeap (),
514 RtlFreeHeap (RtlGetProcessHeap (),
518 /* convert ansi (or oem) string to unicode */
520 RtlUnicodeStringToAnsiString (&Buffer,
524 RtlUnicodeStringToOemString (&Buffer,
528 RtlFreeHeap (RtlGetProcessHeap (),
532 *lpFilePart = strrchr (lpBuffer, '\\') + 1;
549 * FUNCTION: Searches for the specified file
551 * lpPath = Points to a null-terminated string that specified the
552 * path to be searched. If this parameters is NULL then
553 * the following directories are searched
554 * The directory from which the application loaded
555 * The current directory
556 * The system directory
557 * The 16-bit system directory
558 * The windows directory
559 * The directories listed in the PATH environment
561 * lpFileName = Specifies the filename to search for
562 * lpExtension = Points to the null-terminated string that specifies
563 * an extension to be added to the filename when
564 * searching for the file. The first character of the
565 * filename extension must be a period (.). The
566 * extension is only added if the specified filename
567 * doesn't end with an extension
569 * If the filename extension is not required or if the
570 * filename contains an extension, this parameters can be
572 * nBufferLength = The length in characters of the buffer for output
573 * lpBuffer = Points to the buffer for the valid path and filename of
575 * lpFilePart = Points to the last component of the valid path and
577 * RETURNS: On success, the length, in characters, of the string copied to the
584 PWCHAR EnvironmentBufferW = NULL;
587 DPRINT("SearchPath\n");
591 len = GetEnvironmentVariableW(L"PATH", &Buffer, 0);
592 len += 1 + GetCurrentDirectoryW(0, &Buffer);
593 len += 1 + GetSystemDirectoryW(&Buffer, 0);
594 len += 1 + GetWindowsDirectoryW(&Buffer, 0);
596 EnvironmentBufferW = (PWCHAR) RtlAllocateHeap(GetProcessHeap(),
597 HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
598 len * sizeof(WCHAR));
599 if (EnvironmentBufferW == NULL)
601 SetLastError(ERROR_OUTOFMEMORY);
605 pos = GetCurrentDirectoryW(len, EnvironmentBufferW);
606 EnvironmentBufferW[pos++] = L';';
607 EnvironmentBufferW[pos] = 0;
608 pos += GetSystemDirectoryW(&EnvironmentBufferW[pos], len - pos);
609 EnvironmentBufferW[pos++] = L';';
610 EnvironmentBufferW[pos] = 0;
611 pos += GetWindowsDirectoryW(&EnvironmentBufferW[pos], len - pos);
612 EnvironmentBufferW[pos++] = L';';
613 EnvironmentBufferW[pos] = 0;
614 pos += GetEnvironmentVariableW(L"PATH", &EnvironmentBufferW[pos], len - pos);
615 lpPath = EnvironmentBufferW;
618 retCode = RtlDosSearchPath_U ((PWCHAR)lpPath, (PWCHAR)lpFileName, (PWCHAR)lpExtension,
619 nBufferLength * sizeof(WCHAR), lpBuffer, lpFilePart);
621 if (EnvironmentBufferW != NULL)
623 RtlFreeHeap(GetProcessHeap(), 0, EnvironmentBufferW);
627 SetLastError(ERROR_FILE_NOT_FOUND);
629 return retCode / sizeof(WCHAR);