Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfilename.c
Go to the documentation of this file.
00001 /* $Id: file.c 54310 2011-11-06 04:13:21Z ion $ 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS system libraries 00005 * FILE: lib/kernel32/file/file.c 00006 * PURPOSE: Directory functions 00007 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) 00008 * Pierre Schweitzer (pierre.schweitzer@reactos.org) 00009 * UPDATE HISTORY: 00010 * Created 01/11/98 00011 */ 00012 00013 /* INCLUDES *****************************************************************/ 00014 00015 #include <k32.h> 00016 #define NDEBUG 00017 #include <debug.h> 00018 00019 /* GLOBALS ******************************************************************/ 00020 00021 /* FUNCTIONS ****************************************************************/ 00022 00023 /*********************************************************************** 00024 * GetTempFileNameA (KERNEL32.@) 00025 */ 00026 UINT WINAPI 00027 GetTempFileNameA(IN LPCSTR lpPathName, 00028 IN LPCSTR lpPrefixString, 00029 IN UINT uUnique, 00030 OUT LPSTR lpTempFileName) 00031 { 00032 UINT ID; 00033 NTSTATUS Status; 00034 LPWSTR lpTempFileNameW; 00035 PUNICODE_STRING lpPathNameW; 00036 ANSI_STRING TempFileNameStringA; 00037 UNICODE_STRING lpPrefixStringW, TempFileNameStringW; 00038 00039 /* Convert strings */ 00040 lpPathNameW = Basep8BitStringToStaticUnicodeString(lpPathName); 00041 if (!lpPathNameW) 00042 { 00043 return 0; 00044 } 00045 00046 if (!Basep8BitStringToDynamicUnicodeString(&lpPrefixStringW, lpPrefixString)) 00047 { 00048 return 0; 00049 } 00050 00051 lpTempFileNameW = RtlAllocateHeap(RtlGetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); 00052 if (!lpTempFileNameW) 00053 { 00054 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00055 RtlFreeUnicodeString(&lpPrefixStringW); 00056 return 0; 00057 } 00058 00059 /* Call Unicode */ 00060 ID = GetTempFileNameW(lpPathNameW->Buffer, lpPrefixStringW.Buffer, uUnique, lpTempFileNameW); 00061 if (ID) 00062 { 00063 RtlInitUnicodeString(&TempFileNameStringW, lpTempFileNameW); 00064 TempFileNameStringA.Buffer = lpTempFileName; 00065 TempFileNameStringA.MaximumLength = MAX_PATH; 00066 00067 Status = BasepUnicodeStringTo8BitString(&TempFileNameStringA, &TempFileNameStringW, FALSE); 00068 if (!NT_SUCCESS(Status)) 00069 { 00070 BaseSetLastNTError(Status); 00071 ID = 0; 00072 } 00073 } 00074 00075 /* Cleanup */ 00076 RtlFreeUnicodeString(&lpPrefixStringW); 00077 RtlFreeHeap(RtlGetProcessHeap(), 0, lpTempFileNameW); 00078 return ID; 00079 } 00080 00081 /*********************************************************************** 00082 * GetTempFileNameW (KERNEL32.@) 00083 */ 00084 UINT WINAPI 00085 GetTempFileNameW(IN LPCWSTR lpPathName, 00086 IN LPCWSTR lpPrefixString, 00087 IN UINT uUnique, 00088 OUT LPWSTR lpTempFileName) 00089 { 00090 CHAR * Let; 00091 HANDLE TempFile; 00092 UINT ID, Num = 0; 00093 CHAR IDString[5]; 00094 WCHAR * TempFileName; 00095 CSR_API_MESSAGE ApiMessage; 00096 DWORD FileAttributes, LastError; 00097 UNICODE_STRING PathNameString, PrefixString; 00098 static const WCHAR Ext[] = { L'.', 't', 'm', 'p', UNICODE_NULL }; 00099 00100 RtlInitUnicodeString(&PathNameString, lpPathName); 00101 if (PathNameString.Length == 0 || PathNameString.Buffer[(PathNameString.Length / sizeof(WCHAR)) - 1] != L'\\') 00102 { 00103 PathNameString.Length += sizeof(WCHAR); 00104 } 00105 00106 /* lpTempFileName must be able to contain: PathName, Prefix (3), number(4), .tmp(4) & \0(1) 00107 * See: http://msdn.microsoft.com/en-us/library/aa364991%28v=vs.85%29.aspx 00108 */ 00109 if (PathNameString.Length > (MAX_PATH - 3 - 4 - 4 - 1) * sizeof(WCHAR)) 00110 { 00111 SetLastError(ERROR_BUFFER_OVERFLOW); 00112 return 0; 00113 } 00114 00115 /* If PathName and TempFileName aren't the same buffer, move PathName to TempFileName */ 00116 if (lpPathName != lpTempFileName) 00117 { 00118 memmove(lpTempFileName, PathNameString.Buffer, PathNameString.Length); 00119 } 00120 00121 /* PathName MUST BE a path. Check it */ 00122 lpTempFileName[(PathNameString.Length / sizeof(WCHAR)) - 1] = UNICODE_NULL; 00123 FileAttributes = GetFileAttributesW(lpTempFileName); 00124 if (FileAttributes == INVALID_FILE_ATTRIBUTES) 00125 { 00126 /* Append a '\' if necessary */ 00127 lpTempFileName[(PathNameString.Length / sizeof(WCHAR)) - 1] = L'\\'; 00128 lpTempFileName[PathNameString.Length / sizeof(WCHAR)] = UNICODE_NULL; 00129 FileAttributes = GetFileAttributesW(lpTempFileName); 00130 if (FileAttributes == INVALID_FILE_ATTRIBUTES) 00131 { 00132 SetLastError(ERROR_DIRECTORY); 00133 return 0; 00134 } 00135 } 00136 if (!(FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 00137 { 00138 SetLastError(ERROR_DIRECTORY); 00139 return 0; 00140 } 00141 00142 /* Make sure not to mix path & prefix */ 00143 lpTempFileName[(PathNameString.Length / sizeof(WCHAR)) - 1] = L'\\'; 00144 RtlInitUnicodeString(&PrefixString, lpPrefixString); 00145 if (PrefixString.Length > 3 * sizeof(WCHAR)) 00146 { 00147 PrefixString.Length = 3 * sizeof(WCHAR); 00148 } 00149 00150 /* Append prefix to path */ 00151 TempFileName = lpTempFileName + PathNameString.Length / sizeof(WCHAR); 00152 memmove(TempFileName, PrefixString.Buffer, PrefixString.Length); 00153 TempFileName += PrefixString.Length / sizeof(WCHAR); 00154 00155 /* Then, generate filename */ 00156 do 00157 { 00158 /* If user didn't gave any ID, ask Csrss to give one */ 00159 if (!uUnique) 00160 { 00161 CsrClientCallServer(&ApiMessage, NULL, MAKE_CSR_API(GET_TEMP_FILE, CSR_NATIVE), sizeof(CSR_API_MESSAGE)); 00162 if (ApiMessage.Data.GetTempFile.UniqueID == 0) 00163 { 00164 Num++; 00165 continue; 00166 } 00167 00168 ID = ApiMessage.Data.GetTempFile.UniqueID; 00169 } 00170 else 00171 { 00172 ID = uUnique; 00173 } 00174 00175 /* Convert that ID to wchar */ 00176 RtlIntegerToChar(ID, 0x10, sizeof(IDString), IDString); 00177 Let = IDString; 00178 do 00179 { 00180 *(TempFileName++) = RtlAnsiCharToUnicodeChar(&Let); 00181 } while (*Let != 0); 00182 00183 /* Append extension & UNICODE_NULL */ 00184 memmove(TempFileName, Ext, sizeof(Ext)); 00185 00186 /* If user provided its ID, just return */ 00187 if (uUnique) 00188 { 00189 return uUnique; 00190 } 00191 00192 /* Then, try to create file */ 00193 if (!RtlIsDosDeviceName_U(lpTempFileName)) 00194 { 00195 TempFile = CreateFileW(lpTempFileName, 00196 GENERIC_READ, 00197 0, 00198 NULL, 00199 CREATE_NEW, 00200 FILE_ATTRIBUTE_NORMAL, 00201 0); 00202 if (TempFile != INVALID_HANDLE_VALUE) 00203 { 00204 NtClose(TempFile); 00205 DPRINT("Temp file: %S\n", lpTempFileName); 00206 return ID; 00207 } 00208 00209 LastError = GetLastError(); 00210 /* There is no need to recover from those errors, they would hit next step */ 00211 if (LastError == ERROR_INVALID_PARAMETER || LastError == ERROR_CANNOT_MAKE || 00212 LastError == ERROR_WRITE_PROTECT || LastError == ERROR_NETWORK_ACCESS_DENIED || 00213 LastError == ERROR_DISK_FULL || LastError == ERROR_INVALID_NAME || 00214 LastError == ERROR_BAD_PATHNAME || LastError == ERROR_NO_INHERITANCE || 00215 LastError == ERROR_DISK_CORRUPT || 00216 (LastError == ERROR_ACCESS_DENIED && NtCurrentTeb()->LastStatusValue != STATUS_FILE_IS_A_DIRECTORY)) 00217 { 00218 break; 00219 } 00220 } 00221 Num++; 00222 } while (Num & 0xFFFF); 00223 00224 return 0; 00225 } 00226 00227 /* 00228 * @implemented 00229 */ 00230 BOOL 00231 WINAPI 00232 SetFileShortNameW( 00233 HANDLE hFile, 00234 LPCWSTR lpShortName) 00235 { 00236 NTSTATUS Status; 00237 ULONG NeededSize; 00238 UNICODE_STRING ShortName; 00239 IO_STATUS_BLOCK IoStatusBlock; 00240 PFILE_NAME_INFORMATION FileNameInfo; 00241 00242 if(IsConsoleHandle(hFile)) 00243 { 00244 SetLastError(ERROR_INVALID_HANDLE); 00245 return FALSE; 00246 } 00247 00248 if(!lpShortName) 00249 { 00250 SetLastError(ERROR_INVALID_PARAMETER); 00251 return FALSE; 00252 } 00253 00254 RtlInitUnicodeString(&ShortName, lpShortName); 00255 00256 NeededSize = sizeof(FILE_NAME_INFORMATION) + ShortName.Length + sizeof(WCHAR); 00257 if(!(FileNameInfo = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize))) 00258 { 00259 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00260 return FALSE; 00261 } 00262 00263 FileNameInfo->FileNameLength = ShortName.Length; 00264 RtlCopyMemory(FileNameInfo->FileName, ShortName.Buffer, ShortName.Length); 00265 00266 Status = NtSetInformationFile(hFile, 00267 &IoStatusBlock, //out 00268 FileNameInfo, 00269 NeededSize, 00270 FileShortNameInformation); 00271 00272 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInfo); 00273 if(!NT_SUCCESS(Status)) 00274 { 00275 BaseSetLastNTError(Status); 00276 return FALSE; 00277 } 00278 00279 return TRUE; 00280 } 00281 00282 00283 /* 00284 * @implemented 00285 */ 00286 BOOL 00287 WINAPI 00288 SetFileShortNameA( 00289 HANDLE hFile, 00290 LPCSTR lpShortName 00291 ) 00292 { 00293 PWCHAR ShortNameW; 00294 00295 if(IsConsoleHandle(hFile)) 00296 { 00297 SetLastError(ERROR_INVALID_HANDLE); 00298 return FALSE; 00299 } 00300 00301 if(!lpShortName) 00302 { 00303 SetLastError(ERROR_INVALID_PARAMETER); 00304 return FALSE; 00305 } 00306 00307 if (!(ShortNameW = FilenameA2W(lpShortName, FALSE))) 00308 return FALSE; 00309 00310 return SetFileShortNameW(hFile, ShortNameW); 00311 } 00312 00313 00314 /* 00315 * @implemented 00316 */ 00317 BOOL 00318 WINAPI 00319 CheckNameLegalDOS8Dot3W( 00320 LPCWSTR lpName, 00321 LPSTR lpOemName OPTIONAL, 00322 DWORD OemNameSize OPTIONAL, 00323 PBOOL pbNameContainsSpaces OPTIONAL, 00324 PBOOL pbNameLegal 00325 ) 00326 { 00327 UNICODE_STRING Name; 00328 ANSI_STRING AnsiName; 00329 00330 if(lpName == NULL || 00331 (lpOemName == NULL && OemNameSize != 0) || 00332 pbNameLegal == NULL) 00333 { 00334 SetLastError(ERROR_INVALID_PARAMETER); 00335 return FALSE; 00336 } 00337 00338 if(lpOemName != NULL) 00339 { 00340 AnsiName.Buffer = lpOemName; 00341 AnsiName.MaximumLength = (USHORT)OemNameSize * sizeof(CHAR); 00342 AnsiName.Length = 0; 00343 } 00344 00345 RtlInitUnicodeString(&Name, lpName); 00346 00347 *pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name, 00348 (lpOemName ? &AnsiName : NULL), 00349 (BOOLEAN*)pbNameContainsSpaces); 00350 00351 return TRUE; 00352 } 00353 00354 00355 /* 00356 * @implemented 00357 */ 00358 BOOL 00359 WINAPI 00360 CheckNameLegalDOS8Dot3A( 00361 LPCSTR lpName, 00362 LPSTR lpOemName OPTIONAL, 00363 DWORD OemNameSize OPTIONAL, 00364 PBOOL pbNameContainsSpaces OPTIONAL, 00365 PBOOL pbNameLegal 00366 ) 00367 { 00368 UNICODE_STRING Name; 00369 ANSI_STRING AnsiName, AnsiInputName; 00370 NTSTATUS Status; 00371 00372 if(lpName == NULL || 00373 (lpOemName == NULL && OemNameSize != 0) || 00374 pbNameLegal == NULL) 00375 { 00376 SetLastError(ERROR_INVALID_PARAMETER); 00377 return FALSE; 00378 } 00379 00380 if(lpOemName != NULL) 00381 { 00382 AnsiName.Buffer = lpOemName; 00383 AnsiName.MaximumLength = (USHORT)OemNameSize * sizeof(CHAR); 00384 AnsiName.Length = 0; 00385 } 00386 00387 RtlInitAnsiString(&AnsiInputName, (LPSTR)lpName); 00388 if(bIsFileApiAnsi) 00389 Status = RtlAnsiStringToUnicodeString(&Name, &AnsiInputName, TRUE); 00390 else 00391 Status = RtlOemStringToUnicodeString(&Name, &AnsiInputName, TRUE); 00392 00393 if(!NT_SUCCESS(Status)) 00394 { 00395 BaseSetLastNTError(Status); 00396 return FALSE; 00397 } 00398 00399 *pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name, 00400 (lpOemName ? &AnsiName : NULL), 00401 (BOOLEAN*)pbNameContainsSpaces); 00402 00403 RtlFreeUnicodeString(&Name); 00404 00405 return TRUE; 00406 } Generated on Sun May 27 2012 04:24:26 for ReactOS by
1.7.6.1
|