ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

filename.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.