1 /* $Id: dir.c,v 1.36 2003/05/06 06:49:57 gvg 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 *****************************************************************/
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
;
326 DPRINT("GetFullPathNameA(lpFileName %s, nBufferLength %d, lpBuffer %p, "
327 "lpFilePart %p)\n",lpFileName
,nBufferLength
,lpBuffer
,lpFilePart
);
329 RtlInitAnsiString (&FileName
,
332 RtlAnsiStringToUnicodeString (&FileNameU
,
336 BufferLength
= nBufferLength
* sizeof(WCHAR
);
338 FullNameU
.MaximumLength
= BufferLength
;
339 FullNameU
.Length
= 0;
340 FullNameU
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
344 FullNameU
.Length
= RtlGetFullPathName_U (FileNameU
.Buffer
,
349 RtlFreeUnicodeString (&FileNameU
);
351 FullName
.MaximumLength
= nBufferLength
;
353 FullName
.Buffer
= lpBuffer
;
355 if (lpBuffer
!= NULL
)
357 RtlUnicodeStringToAnsiString (&FullName
,
361 if (lpFilePart
!= NULL
)
363 Offset
= (ULONG
)(FilePartU
- FullNameU
.Buffer
);
364 *lpFilePart
= FullName
.Buffer
+ Offset
;
368 FullNameLen
= FullNameU
.Length
/ sizeof(WCHAR
);
370 RtlFreeHeap (RtlGetProcessHeap (),
374 DPRINT("lpBuffer %s lpFilePart %s Length %ld\n",
375 lpBuffer
, lpFilePart
, FullName
.Length
);
392 DPRINT("GetFullPathNameW(lpFileName %S, nBufferLength %d, lpBuffer %p, "
393 "lpFilePart %p)\n",lpFileName
,nBufferLength
,lpBuffer
,lpFilePart
);
395 Length
= RtlGetFullPathName_U ((LPWSTR
)lpFileName
,
396 nBufferLength
* sizeof(WCHAR
),
400 DPRINT("lpBuffer %S lpFilePart %S Length %ld\n",
401 lpBuffer
, lpFilePart
, Length
/ sizeof(WCHAR
));
403 return (Length
/ sizeof(WCHAR
));
415 //1 remove unicode chars and spaces
416 //2 remove preceding and trailing periods.
417 //3 remove embedded periods except the last one
419 //4 Split the string in two parts before and after the period
420 // truncate the part before the period to 6 chars and add ~1
421 // truncate the part after the period to 3 chars
422 //3 Put the new name in uppercase
424 //4 Increment the ~1 string if the resulting name allready exists
433 LPCWSTR lpszLongPath
,
434 LPWSTR lpszShortPath
,
453 UNICODE_STRING PathU
;
454 UNICODE_STRING FileNameU
;
455 UNICODE_STRING ExtensionU
;
456 UNICODE_STRING BufferU
;
458 ANSI_STRING FileName
;
459 ANSI_STRING Extension
;
464 RtlInitAnsiString (&Path
,
466 RtlInitAnsiString (&FileName
,
468 RtlInitAnsiString (&Extension
,
471 /* convert ansi (or oem) strings to unicode */
474 RtlAnsiStringToUnicodeString (&PathU
,
477 RtlAnsiStringToUnicodeString (&FileNameU
,
480 RtlAnsiStringToUnicodeString (&ExtensionU
,
486 RtlOemStringToUnicodeString (&PathU
,
489 RtlOemStringToUnicodeString (&FileNameU
,
492 RtlOemStringToUnicodeString (&ExtensionU
,
498 BufferU
.MaximumLength
= nBufferLength
* sizeof(WCHAR
);
499 BufferU
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
501 BufferU
.MaximumLength
);
504 Buffer
.MaximumLength
= nBufferLength
;
505 Buffer
.Buffer
= lpBuffer
;
507 RetValue
= SearchPathW (PathU
.Buffer
,
514 RtlFreeHeap (RtlGetProcessHeap (),
517 RtlFreeHeap (RtlGetProcessHeap (),
520 RtlFreeHeap (RtlGetProcessHeap (),
524 /* convert ansi (or oem) string to unicode */
526 RtlUnicodeStringToAnsiString (&Buffer
,
530 RtlUnicodeStringToOemString (&Buffer
,
534 RtlFreeHeap (RtlGetProcessHeap (),
538 *lpFilePart
= strrchr (lpBuffer
, '\\') + 1;
555 * FUNCTION: Searches for the specified file
557 * lpPath = Points to a null-terminated string that specified the
558 * path to be searched. If this parameters is NULL then
559 * the following directories are searched
560 * The directory from which the application loaded
561 * The current directory
562 * The system directory
563 * The 16-bit system directory
564 * The windows directory
565 * The directories listed in the PATH environment
567 * lpFileName = Specifies the filename to search for
568 * lpExtension = Points to the null-terminated string that specifies
569 * an extension to be added to the filename when
570 * searching for the file. The first character of the
571 * filename extension must be a period (.). The
572 * extension is only added if the specified filename
573 * doesn't end with an extension
575 * If the filename extension is not required or if the
576 * filename contains an extension, this parameters can be
578 * nBufferLength = The length in characters of the buffer for output
579 * lpBuffer = Points to the buffer for the valid path and filename of
581 * lpFilePart = Points to the last component of the valid path and
583 * RETURNS: On success, the length, in characters, of the string copied to the
590 PWCHAR EnvironmentBufferW
= NULL
;
593 DPRINT("SearchPath\n");
597 len
= GetEnvironmentVariableW(L
"PATH", &Buffer
, 0);
598 len
+= 1 + GetCurrentDirectoryW(0, &Buffer
);
599 len
+= 1 + GetSystemDirectoryW(&Buffer
, 0);
600 len
+= 1 + GetWindowsDirectoryW(&Buffer
, 0);
602 EnvironmentBufferW
= (PWCHAR
) RtlAllocateHeap(GetProcessHeap(),
603 HEAP_GENERATE_EXCEPTIONS
|HEAP_ZERO_MEMORY
,
604 len
* sizeof(WCHAR
));
605 if (EnvironmentBufferW
== NULL
)
607 SetLastError(ERROR_OUTOFMEMORY
);
611 pos
= GetCurrentDirectoryW(len
, EnvironmentBufferW
);
612 EnvironmentBufferW
[pos
++] = L
';';
613 EnvironmentBufferW
[pos
] = 0;
614 pos
+= GetSystemDirectoryW(&EnvironmentBufferW
[pos
], len
- pos
);
615 EnvironmentBufferW
[pos
++] = L
';';
616 EnvironmentBufferW
[pos
] = 0;
617 pos
+= GetWindowsDirectoryW(&EnvironmentBufferW
[pos
], len
- pos
);
618 EnvironmentBufferW
[pos
++] = L
';';
619 EnvironmentBufferW
[pos
] = 0;
620 pos
+= GetEnvironmentVariableW(L
"PATH", &EnvironmentBufferW
[pos
], len
- pos
);
621 lpPath
= EnvironmentBufferW
;
624 retCode
= RtlDosSearchPath_U ((PWCHAR
)lpPath
, (PWCHAR
)lpFileName
, (PWCHAR
)lpExtension
,
625 nBufferLength
* sizeof(WCHAR
), lpBuffer
, lpFilePart
);
627 if (EnvironmentBufferW
!= NULL
)
629 RtlFreeHeap(GetProcessHeap(), 0, EnvironmentBufferW
);
633 SetLastError(ERROR_FILE_NOT_FOUND
);
635 return retCode
/ sizeof(WCHAR
);