ReactOS 0.4.15-dev-8127-g6338913
filename.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/file/filename.c
5 * PURPOSE: Directory functions
6 * PROGRAMMERS: Ariadne (ariadne@xs4all.nl)
7 * Pierre Schweitzer (pierre.schweitzer@reactos.org)
8 * UPDATE HISTORY:
9 * Created 01/11/98
10 */
11
12/* INCLUDES *****************************************************************/
13
14#include <k32.h>
15#define NDEBUG
16#include <debug.h>
17
18/* GLOBALS ******************************************************************/
19
20/* FUNCTIONS ****************************************************************/
21
22/***********************************************************************
23 * GetTempFileNameA (KERNEL32.@)
24 */
27 IN LPCSTR lpPrefixString,
28 IN UINT uUnique,
29 OUT LPSTR lpTempFileName)
30{
31 UINT ID;
33 LPWSTR lpTempFileNameW;
34 PUNICODE_STRING lpPathNameW;
35 ANSI_STRING TempFileNameStringA;
36 UNICODE_STRING lpPrefixStringW, TempFileNameStringW;
37
38 /* Convert strings */
39 lpPathNameW = Basep8BitStringToStaticUnicodeString(lpPathName);
40 if (!lpPathNameW)
41 {
42 return 0;
43 }
44
45 if (!Basep8BitStringToDynamicUnicodeString(&lpPrefixStringW, lpPrefixString))
46 {
47 return 0;
48 }
49
50 lpTempFileNameW = RtlAllocateHeap(RtlGetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
51 if (!lpTempFileNameW)
52 {
54 RtlFreeUnicodeString(&lpPrefixStringW);
55 return 0;
56 }
57
58 /* Call Unicode */
59 ID = GetTempFileNameW(lpPathNameW->Buffer, lpPrefixStringW.Buffer, uUnique, lpTempFileNameW);
60 if (ID)
61 {
62 RtlInitUnicodeString(&TempFileNameStringW, lpTempFileNameW);
63 TempFileNameStringA.Buffer = lpTempFileName;
64 TempFileNameStringA.MaximumLength = MAX_PATH;
65
66 Status = BasepUnicodeStringTo8BitString(&TempFileNameStringA, &TempFileNameStringW, FALSE);
67 if (!NT_SUCCESS(Status))
68 {
70 ID = 0;
71 }
72 }
73
74 /* Cleanup */
75 RtlFreeUnicodeString(&lpPrefixStringW);
76 RtlFreeHeap(RtlGetProcessHeap(), 0, lpTempFileNameW);
77 return ID;
78 }
79
80 /***********************************************************************
81 * GetTempFileNameW (KERNEL32.@)
82 */
85 IN LPCWSTR lpPrefixString,
86 IN UINT uUnique,
87 OUT LPWSTR lpTempFileName)
88{
89 PUCHAR Let;
90 HANDLE TempFile;
91 UINT ID, Num = 0;
92 UCHAR IDString[5];
93 WCHAR * TempFileName;
94 BASE_API_MESSAGE ApiMessage;
95 PBASE_GET_TEMP_FILE GetTempFile = &ApiMessage.Data.GetTempFileRequest;
96 DWORD FileAttributes, LastError;
97 UNICODE_STRING PathNameString, PrefixString;
98 static const WCHAR Ext[] = { L'.', 't', 'm', 'p', UNICODE_NULL };
99
100 RtlInitUnicodeString(&PathNameString, lpPathName);
101 if (PathNameString.Length == 0 || PathNameString.Buffer[(PathNameString.Length / sizeof(WCHAR)) - 1] != L'\\')
102 {
103 PathNameString.Length += sizeof(WCHAR);
104 }
105
106 /* lpTempFileName must be able to contain: PathName, Prefix (3), number(4), .tmp(4) & \0(1)
107 * See: http://msdn.microsoft.com/en-us/library/aa364991%28v=vs.85%29.aspx
108 */
109 if (PathNameString.Length > (MAX_PATH - 3 - 4 - 4 - 1) * sizeof(WCHAR))
110 {
112 return 0;
113 }
114
115 /* If PathName and TempFileName aren't the same buffer, move PathName to TempFileName */
116 if (lpPathName != lpTempFileName)
117 {
118 memmove(lpTempFileName, PathNameString.Buffer, PathNameString.Length);
119 }
120
121 /* PathName MUST BE a path. Check it */
122 lpTempFileName[(PathNameString.Length / sizeof(WCHAR)) - 1] = UNICODE_NULL;
123 FileAttributes = GetFileAttributesW(lpTempFileName);
125 {
126 /* Append a '\' if necessary */
127 lpTempFileName[(PathNameString.Length / sizeof(WCHAR)) - 1] = L'\\';
128 lpTempFileName[PathNameString.Length / sizeof(WCHAR)] = UNICODE_NULL;
129 FileAttributes = GetFileAttributesW(lpTempFileName);
131 {
133 return 0;
134 }
135 }
137 {
139 return 0;
140 }
141
142 /* Make sure not to mix path & prefix */
143 lpTempFileName[(PathNameString.Length / sizeof(WCHAR)) - 1] = L'\\';
144 RtlInitUnicodeString(&PrefixString, lpPrefixString);
145 if (PrefixString.Length > 3 * sizeof(WCHAR))
146 {
147 PrefixString.Length = 3 * sizeof(WCHAR);
148 }
149
150 /* Append prefix to path */
151 TempFileName = lpTempFileName + PathNameString.Length / sizeof(WCHAR);
152 memmove(TempFileName, PrefixString.Buffer, PrefixString.Length);
153 TempFileName += PrefixString.Length / sizeof(WCHAR);
154
155 /* Then, generate filename */
156 do
157 {
158 /* If user didn't gave any ID, ask Csrss to give one */
159 if (!uUnique)
160 {
162 NULL,
164 sizeof(*GetTempFile));
165 if (GetTempFile->UniqueID == 0)
166 {
167 Num++;
168 continue;
169 }
170
171 ID = GetTempFile->UniqueID;
172 }
173 else
174 {
175 ID = uUnique;
176 }
177
178 /* Convert that ID to wchar */
179 RtlIntegerToChar(ID, 0x10, sizeof(IDString), (PCHAR)IDString);
180 Let = IDString;
181 do
182 {
183 *(TempFileName++) = RtlAnsiCharToUnicodeChar(&Let);
184 } while (*Let != 0);
185
186 /* Append extension & UNICODE_NULL */
187 memmove(TempFileName, Ext, sizeof(Ext));
188
189 /* If user provided its ID, just return */
190 if (uUnique)
191 {
192 return uUnique;
193 }
194
195 /* Then, try to create file */
196 if (!RtlIsDosDeviceName_U(lpTempFileName))
197 {
198 TempFile = CreateFileW(lpTempFileName,
200 0,
201 NULL,
204 0);
205 if (TempFile != INVALID_HANDLE_VALUE)
206 {
207 NtClose(TempFile);
208 DPRINT("Temp file: %S\n", lpTempFileName);
209 return ID;
210 }
211
212 LastError = GetLastError();
213 /* There is no need to recover from those errors, they would hit next step */
214 if (LastError == ERROR_INVALID_PARAMETER || LastError == ERROR_CANNOT_MAKE ||
215 LastError == ERROR_WRITE_PROTECT || LastError == ERROR_NETWORK_ACCESS_DENIED ||
216 LastError == ERROR_DISK_FULL || LastError == ERROR_INVALID_NAME ||
217 LastError == ERROR_BAD_PATHNAME || LastError == ERROR_NO_INHERITANCE ||
218 LastError == ERROR_DISK_CORRUPT ||
219 (LastError == ERROR_ACCESS_DENIED && NtCurrentTeb()->LastStatusValue != STATUS_FILE_IS_A_DIRECTORY))
220 {
221 break;
222 }
223 }
224 Num++;
225 } while (Num & 0xFFFF);
226
227 return 0;
228}
229
230/*
231 * @implemented
232 */
233BOOL
234WINAPI
237 LPCWSTR lpShortName)
238{
240 ULONG NeededSize;
243 PFILE_NAME_INFORMATION FileNameInfo;
244
246 {
248 return FALSE;
249 }
250
251 if(!lpShortName)
252 {
254 return FALSE;
255 }
256
257 RtlInitUnicodeString(&ShortName, lpShortName);
258
259 NeededSize = sizeof(FILE_NAME_INFORMATION) + ShortName.Length + sizeof(WCHAR);
260 if(!(FileNameInfo = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize)))
261 {
263 return FALSE;
264 }
265
266 FileNameInfo->FileNameLength = ShortName.Length;
267 RtlCopyMemory(FileNameInfo->FileName, ShortName.Buffer, ShortName.Length);
268
270 &IoStatusBlock, //out
271 FileNameInfo,
272 NeededSize,
274
275 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInfo);
276 if(!NT_SUCCESS(Status))
277 {
279 return FALSE;
280 }
281
282 return TRUE;
283}
284
285
286/*
287 * @implemented
288 */
289BOOL
290WINAPI
293 LPCSTR lpShortName)
294{
295 PWCHAR ShortNameW;
296
298 {
300 return FALSE;
301 }
302
303 if(!lpShortName)
304 {
306 return FALSE;
307 }
308
309 if (!(ShortNameW = FilenameA2W(lpShortName, FALSE)))
310 return FALSE;
311
312 return SetFileShortNameW(hFile, ShortNameW);
313}
314
315
316/*
317 * @implemented
318 */
319BOOL
320WINAPI
323 LPSTR lpOemName OPTIONAL,
324 DWORD OemNameSize OPTIONAL,
325 PBOOL pbNameContainsSpaces OPTIONAL,
326 PBOOL pbNameLegal
327 )
328{
330 ANSI_STRING AnsiName;
332
333 if(lpName == NULL ||
334 (lpOemName == NULL && OemNameSize != 0) ||
335 pbNameLegal == NULL)
336 {
338 return FALSE;
339 }
340
341 if(lpOemName != NULL)
342 {
343 AnsiName.Buffer = lpOemName;
344 AnsiName.MaximumLength = (USHORT)OemNameSize * sizeof(CHAR);
345 AnsiName.Length = 0;
346 }
347
349
350 *pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name,
351 (lpOemName ? &AnsiName : NULL),
353 if (*pbNameLegal && pbNameContainsSpaces)
354 *pbNameContainsSpaces = NameContainsSpaces;
355
356 return TRUE;
357}
358
359
360/*
361 * @implemented
362 */
363BOOL
364WINAPI
367 LPSTR lpOemName OPTIONAL,
368 DWORD OemNameSize OPTIONAL,
369 PBOOL pbNameContainsSpaces OPTIONAL,
370 PBOOL pbNameLegal
371 )
372{
374 ANSI_STRING AnsiName, AnsiInputName;
377
378 if(lpName == NULL ||
379 (lpOemName == NULL && OemNameSize != 0) ||
380 pbNameLegal == NULL)
381 {
383 return FALSE;
384 }
385
386 if(lpOemName != NULL)
387 {
388 AnsiName.Buffer = lpOemName;
389 AnsiName.MaximumLength = (USHORT)OemNameSize * sizeof(CHAR);
390 AnsiName.Length = 0;
391 }
392
393 RtlInitAnsiString(&AnsiInputName, (LPSTR)lpName);
395 Status = RtlAnsiStringToUnicodeString(&Name, &AnsiInputName, TRUE);
396 else
397 Status = RtlOemStringToUnicodeString(&Name, &AnsiInputName, TRUE);
398
399 if(!NT_SUCCESS(Status))
400 {
402 return FALSE;
403 }
404
405 *pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name,
406 (lpOemName ? &AnsiName : NULL),
408 if (*pbNameLegal && pbNameContainsSpaces)
409 *pbNameContainsSpaces = NameContainsSpaces;
410
412
413 return TRUE;
414}
unsigned char BOOLEAN
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
@ BasepGetTempFile
Definition: basemsg.h:23
#define BASESRV_SERVERDLL_INDEX
Definition: basemsg.h:15
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
PWCHAR FilenameA2W(LPCSTR NameA, BOOL alloc)
Definition: fileutils.c:18
PRTL_CONVERT_STRINGA BasepUnicodeStringTo8BitString
Definition: utils.c:27
BOOLEAN WINAPI Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, IN LPCSTR String)
Definition: utils.c:225
PUNICODE_STRING WINAPI Basep8BitStringToStaticUnicodeString(IN LPCSTR String)
Definition: utils.c:188
BOOL bIsFileApiAnsi
Definition: utils.c:25
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1306
BOOL WINAPI CheckNameLegalDOS8Dot3W(LPCWSTR lpName, LPSTR lpOemName OPTIONAL, DWORD OemNameSize OPTIONAL, PBOOL pbNameContainsSpaces OPTIONAL, PBOOL pbNameLegal)
Definition: filename.c:321
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
BOOL WINAPI SetFileShortNameW(HANDLE hFile, LPCWSTR lpShortName)
Definition: filename.c:235
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
BOOL WINAPI SetFileShortNameA(HANDLE hFile, LPCSTR lpShortName)
Definition: filename.c:291
BOOL WINAPI CheckNameLegalDOS8Dot3A(LPCSTR lpName, LPSTR lpOemName OPTIONAL, DWORD OemNameSize OPTIONAL, PBOOL pbNameContainsSpaces OPTIONAL, PBOOL pbNameLegal)
Definition: filename.c:365
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1236
@ FileShortNameInformation
Definition: from_kernel.h:101
Status
Definition: gdiplustypes.h:25
BOOLEAN NTAPI RtlIsNameLegalDOS8Dot3(_In_ PUNICODE_STRING Name, _Inout_opt_ POEM_STRING OemName, _Inout_opt_ PBOOLEAN NameContainsSpaces)
NTSYSAPI WCHAR WINAPI RtlAnsiCharToUnicodeChar(LPSTR *)
struct _FILE_NAME_INFORMATION FILE_NAME_INFORMATION
#define NtCurrentTeb
static struct proto Ext[]
Definition: mkg3states.c:87
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define CREATE_NEW
Definition: disk.h:69
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)
_Inout_opt_ POEM_STRING _Out_opt_ PBOOLEAN NameContainsSpaces
Definition: rtlfuncs.h:3091
NTSYSAPI NTSTATUS NTAPI RtlOemStringToUnicodeString(PUNICODE_STRING DestinationString, PCOEM_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI NTSTATUS NTAPI RtlIntegerToChar(_In_ ULONG Value, _In_ ULONG Base, _In_ ULONG Length, _Out_ PCHAR String)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
#define ID
Definition: ruserpass.c:36
NTSTATUS NTAPI CsrClientCallServer(_Inout_ PCSR_API_MESSAGE ApiMessage, _Inout_opt_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_ CSR_API_NUMBER ApiNumber, _In_ ULONG DataLength)
Definition: connect.c:366
#define IsConsoleHandle(h)
Definition: console.h:14
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
USHORT MaximumLength
Definition: env_spec_w32.h:377
BASE_GET_TEMP_FILE GetTempFileRequest
Definition: basemsg.h:285
union _BASE_API_MESSAGE::@3543 Data
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LPCSTR lpName
Definition: winbase.h:2789
BOOL * PBOOL
Definition: windef.h:161
#define WINAPI
Definition: msvc.h:6
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define ERROR_WRITE_PROTECT
Definition: winerror.h:122
#define ERROR_DIRECTORY
Definition: winerror.h:295
#define ERROR_BAD_PATHNAME
Definition: winerror.h:233
#define ERROR_DISK_FULL
Definition: winerror.h:186
#define ERROR_NO_INHERITANCE
Definition: winerror.h:872
#define ERROR_CANNOT_MAKE
Definition: winerror.h:166
#define ERROR_DISK_CORRUPT
Definition: winerror.h:874
#define ERROR_NETWORK_ACCESS_DENIED
Definition: winerror.h:157
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175