1 /* $Id: dir.c,v 1.37 2003/07/10 18:50:51 chorns Exp $
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
);