ReactOS  0.4.13-dev-92-gf251225
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,
199  GENERIC_READ,
200  0,
201  NULL,
202  CREATE_NEW,
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  */
233 BOOL
234 WINAPI
236  HANDLE hFile,
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  */
289 BOOL
290 WINAPI
292  HANDLE hFile,
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  */
319 BOOL
320 WINAPI
322  LPCWSTR lpName,
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  */
363 BOOL
364 WINAPI
366  LPCSTR lpName,
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);
394  if(bIsFileApiAnsi)
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 }
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1294
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL WINAPI SetFileShortNameA(HANDLE hFile, LPCSTR lpShortName)
Definition: filename.c:291
#define IN
Definition: typedefs.h:38
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
PUNICODE_STRING WINAPI Basep8BitStringToStaticUnicodeString(IN LPCSTR String)
Definition: utils.c:188
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
BOOL WINAPI CheckNameLegalDOS8Dot3A(LPCSTR lpName, LPSTR lpOemName OPTIONAL, DWORD OemNameSize OPTIONAL, PBOOL pbNameContainsSpaces OPTIONAL, PBOOL pbNameLegal)
Definition: filename.c:365
BOOL bIsFileApiAnsi
Definition: utils.c:25
_Inout_opt_ POEM_STRING _Out_opt_ PBOOLEAN NameContainsSpaces
Definition: rtlfuncs.h:2961
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
struct _FILE_NAME_INFORMATION FILE_NAME_INFORMATION
PRTL_CONVERT_STRINGA BasepUnicodeStringTo8BitString
Definition: utils.c:27
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define ERROR_WRITE_PROTECT
Definition: winerror.h:122
union _BASE_API_MESSAGE::@3379 Data
#define ERROR_DISK_FULL
Definition: winerror.h:186
NTSTATUS NTAPI CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, IN CSR_API_NUMBER ApiNumber, IN ULONG DataLength)
Definition: connect.c:360
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
_In_ LPCSTR lpName
Definition: winbase.h:2729
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_CANNOT_MAKE
Definition: winerror.h:166
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSYSAPI NTSTATUS NTAPI RtlIntegerToChar(_In_ ULONG Value, _In_ ULONG Base, _In_ ULONG Length, _Out_ PCHAR String)
char * LPSTR
Definition: xmlstorage.h:182
#define ERROR_DIRECTORY
Definition: winerror.h:295
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
BOOL WINAPI SetFileShortNameW(HANDLE hFile, LPCWSTR lpShortName)
Definition: filename.c:235
BOOLEAN WINAPI Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, IN LPCSTR String)
Definition: utils.c:225
#define UNICODE_NULL
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:802
struct NameRec_ * Name
Definition: cdprocs.h:464
#define ERROR_NO_INHERITANCE
Definition: winerror.h:872
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
BASE_GET_TEMP_FILE GetTempFileRequest
Definition: basemsg.h:285
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
const char * LPCSTR
Definition: xmlstorage.h:183
BOOL * PBOOL
Definition: windef.h:161
_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:1230
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
PWCHAR FilenameA2W(LPCSTR NameA, BOOL alloc)
Definition: fileinfo.c:22
USHORT MaximumLength
Definition: env_spec_w32.h:377
#define BASESRV_SERVERDLL_INDEX
Definition: basemsg.h:15
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOL WINAPI CheckNameLegalDOS8Dot3W(LPCWSTR lpName, LPSTR lpOemName OPTIONAL, DWORD OemNameSize OPTIONAL, PBOOL pbNameContainsSpaces OPTIONAL, PBOOL pbNameLegal)
Definition: filename.c:321
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:409
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static struct proto Ext[]
Definition: mkg3states.c:87
#define IsConsoleHandle(h)
Definition: console.h:14
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
unsigned char UCHAR
Definition: xmlstorage.h:181
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:124
#define ID
Definition: ruserpass.c:36
_In_ HANDLE hFile
Definition: mswsock.h:90
NTSYSAPI NTSTATUS NTAPI RtlOemStringToUnicodeString(PUNICODE_STRING DestinationString, PCOEM_STRING SourceString, BOOLEAN AllocateDestinationString)
Status
Definition: gdiplustypes.h:24
#define ERROR_DISK_CORRUPT
Definition: winerror.h:874
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define ERROR_NETWORK_ACCESS_DENIED
Definition: winerror.h:157
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int UINT
Definition: ndis.h:50
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define CreateFileW
Definition: compat.h:400
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ERROR_INVALID_NAME
Definition: compat.h:93
#define CREATE_NEW
Definition: disk.h:69
WCHAR * LPWSTR
Definition: xmlstorage.h:184
NTSYSAPI WCHAR WINAPI RtlAnsiCharToUnicodeChar(LPSTR *)
#define ERROR_BAD_PATHNAME
Definition: winerror.h:233
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
BOOLEAN NTAPI RtlIsNameLegalDOS8Dot3(_In_ PUNICODE_STRING Name, _Inout_opt_ POEM_STRING OemName, _Inout_opt_ PBOOLEAN NameContainsSpaces)
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:3042
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68