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

create.c
Go to the documentation of this file.
00001 /* $Id: create.c 54326 2011-11-07 00:18:13Z ion $
00002  *
00003  * COPYRIGHT:       See COPYING in the top level directory
00004  * PROJECT:         ReactOS system libraries
00005  * FILE:            lib/kernel32/file/create.c
00006  * PURPOSE:         Directory functions
00007  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
00008  * UPDATE HISTORY:
00009  *                  Created 01/11/98
00010  *                  Removed use of SearchPath (not used by Windows)
00011  *                  18/08/2002: CreateFileW mess cleaned up (KJK::Hyperion)
00012  *                  24/08/2002: removed superfluous DPRINTs (KJK::Hyperion)
00013  */
00014 
00015 /* INCLUDES *****************************************************************/
00016 
00017 #include <k32.h>
00018 #define NDEBUG
00019 #include <debug.h>
00020 
00021 #if DBG
00022 DEBUG_CHANNEL(kernel32file);
00023 #endif
00024 
00025 #define SYMLINK_FLAG_RELATIVE   1
00026 
00027 typedef struct _REPARSE_DATA_BUFFER {
00028     ULONG  ReparseTag;
00029     USHORT ReparseDataLength;
00030     USHORT Reserved;
00031     union {
00032         struct {
00033             USHORT SubstituteNameOffset;
00034             USHORT SubstituteNameLength;
00035             USHORT PrintNameOffset;
00036             USHORT PrintNameLength;
00037             ULONG Flags;
00038             WCHAR PathBuffer[1];
00039         } SymbolicLinkReparseBuffer;
00040         struct {
00041             USHORT SubstituteNameOffset;
00042             USHORT SubstituteNameLength;
00043             USHORT PrintNameOffset;
00044             USHORT PrintNameLength;
00045             WCHAR PathBuffer[1];
00046         } MountPointReparseBuffer;
00047         struct {
00048             UCHAR  DataBuffer[1];
00049         } GenericReparseBuffer;
00050     };
00051 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
00052 
00053 #define REPARSE_DATA_BUFFER_HEADER_SIZE   FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
00054 
00055 /* FUNCTIONS ****************************************************************/
00056 
00057 /*
00058  * @implemented
00059  */
00060 HANDLE WINAPI CreateFileA (LPCSTR           lpFileName,
00061                 DWORD           dwDesiredAccess,
00062                 DWORD           dwShareMode,
00063                 LPSECURITY_ATTRIBUTES   lpSecurityAttributes,
00064                 DWORD           dwCreationDisposition,
00065                 DWORD           dwFlagsAndAttributes,
00066                 HANDLE          hTemplateFile)
00067 {
00068    PWCHAR FileNameW;
00069    HANDLE FileHandle;
00070 
00071    TRACE("CreateFileA(lpFileName %s)\n",lpFileName);
00072 
00073    if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
00074       return INVALID_HANDLE_VALUE;
00075 
00076    FileHandle = CreateFileW (FileNameW,
00077                  dwDesiredAccess,
00078                  dwShareMode,
00079                  lpSecurityAttributes,
00080                  dwCreationDisposition,
00081                  dwFlagsAndAttributes,
00082                  hTemplateFile);
00083 
00084    return FileHandle;
00085 }
00086 
00087 
00088 /*
00089  * @implemented
00090  */
00091 HANDLE WINAPI CreateFileW (LPCWSTR          lpFileName,
00092                 DWORD           dwDesiredAccess,
00093                 DWORD           dwShareMode,
00094                 LPSECURITY_ATTRIBUTES   lpSecurityAttributes,
00095                 DWORD           dwCreationDisposition,
00096                 DWORD           dwFlagsAndAttributes,
00097                 HANDLE          hTemplateFile)
00098 {
00099    OBJECT_ATTRIBUTES ObjectAttributes;
00100    IO_STATUS_BLOCK IoStatusBlock;
00101    UNICODE_STRING NtPathU;
00102    HANDLE FileHandle;
00103    NTSTATUS Status;
00104    ULONG FileAttributes, Flags = 0;
00105    PVOID EaBuffer = NULL;
00106    ULONG EaLength = 0;
00107 
00108    if (!lpFileName || !lpFileName[0])
00109    {
00110        SetLastError( ERROR_PATH_NOT_FOUND );
00111        return INVALID_HANDLE_VALUE;
00112    }
00113 
00114    TRACE("CreateFileW(lpFileName %S)\n",lpFileName);
00115 
00116    /* validate & translate the creation disposition */
00117    switch (dwCreationDisposition)
00118      {
00119       case CREATE_NEW:
00120     dwCreationDisposition = FILE_CREATE;
00121     break;
00122 
00123       case CREATE_ALWAYS:
00124     dwCreationDisposition = FILE_OVERWRITE_IF;
00125     break;
00126 
00127       case OPEN_EXISTING:
00128     dwCreationDisposition = FILE_OPEN;
00129     break;
00130 
00131       case OPEN_ALWAYS:
00132     dwCreationDisposition = FILE_OPEN_IF;
00133     break;
00134 
00135       case TRUNCATE_EXISTING:
00136     dwCreationDisposition = FILE_OVERWRITE;
00137         break;
00138 
00139       default:
00140         SetLastError(ERROR_INVALID_PARAMETER);
00141         return (INVALID_HANDLE_VALUE);
00142      }
00143 
00144    /* check for console input/output */
00145    if (0 == _wcsicmp(L"CONOUT$", lpFileName)
00146        || 0 == _wcsicmp(L"CONIN$", lpFileName))
00147    {
00148       return OpenConsoleW(lpFileName,
00149                           dwDesiredAccess,
00150                           lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE,
00151                           FILE_SHARE_READ | FILE_SHARE_WRITE);
00152    }
00153 
00154   /* validate & translate the flags */
00155 
00156    /* translate the flags that need no validation */
00157    if (!(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
00158    {
00159       /* yes, nonalert is correct! apc's are not delivered
00160       while waiting for file io to complete */
00161       Flags |= FILE_SYNCHRONOUS_IO_NONALERT;
00162    }
00163 
00164    if(dwFlagsAndAttributes & FILE_FLAG_WRITE_THROUGH)
00165       Flags |= FILE_WRITE_THROUGH;
00166 
00167    if(dwFlagsAndAttributes & FILE_FLAG_NO_BUFFERING)
00168       Flags |= FILE_NO_INTERMEDIATE_BUFFERING;
00169 
00170    if(dwFlagsAndAttributes & FILE_FLAG_RANDOM_ACCESS)
00171       Flags |= FILE_RANDOM_ACCESS;
00172 
00173    if(dwFlagsAndAttributes & FILE_FLAG_SEQUENTIAL_SCAN)
00174       Flags |= FILE_SEQUENTIAL_ONLY;
00175 
00176    if(dwFlagsAndAttributes & FILE_FLAG_DELETE_ON_CLOSE)
00177       Flags |= FILE_DELETE_ON_CLOSE;
00178 
00179    if(dwFlagsAndAttributes & FILE_FLAG_BACKUP_SEMANTICS)
00180    {
00181       if(dwDesiredAccess & GENERIC_ALL)
00182          Flags |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REMOTE_INSTANCE;
00183       else
00184       {
00185          if(dwDesiredAccess & GENERIC_READ)
00186             Flags |= FILE_OPEN_FOR_BACKUP_INTENT;
00187 
00188          if(dwDesiredAccess & GENERIC_WRITE)
00189             Flags |= FILE_OPEN_REMOTE_INSTANCE;
00190       }
00191    }
00192    else
00193       Flags |= FILE_NON_DIRECTORY_FILE;
00194 
00195    if(dwFlagsAndAttributes & FILE_FLAG_OPEN_REPARSE_POINT)
00196       Flags |= FILE_OPEN_REPARSE_POINT;
00197 
00198    if(dwFlagsAndAttributes & FILE_FLAG_OPEN_NO_RECALL)
00199       Flags |= FILE_OPEN_NO_RECALL;
00200 
00201    FileAttributes = (dwFlagsAndAttributes & (FILE_ATTRIBUTE_VALID_FLAGS & ~FILE_ATTRIBUTE_DIRECTORY));
00202 
00203    /* handle may allways be waited on and querying attributes are allways allowed */
00204    dwDesiredAccess |= SYNCHRONIZE | FILE_READ_ATTRIBUTES;
00205 
00206    /* FILE_FLAG_POSIX_SEMANTICS is handled later */
00207 
00208    /* validate & translate the filename */
00209    if (!RtlDosPathNameToNtPathName_U (lpFileName,
00210                       &NtPathU,
00211                       NULL,
00212                       NULL))
00213    {
00214      WARN("Invalid path\n");
00215      SetLastError(ERROR_FILE_NOT_FOUND);
00216      return INVALID_HANDLE_VALUE;
00217    }
00218 
00219    TRACE("NtPathU \'%wZ\'\n", &NtPathU);
00220 
00221    if (hTemplateFile != NULL)
00222    {
00223       FILE_EA_INFORMATION EaInformation;
00224 
00225       for (;;)
00226       {
00227          /* try to get the size of the extended attributes, if we fail just continue
00228             creating the file without copying the attributes! */
00229          Status = NtQueryInformationFile(hTemplateFile,
00230                                          &IoStatusBlock,
00231                                          &EaInformation,
00232                                          sizeof(FILE_EA_INFORMATION),
00233                                          FileEaInformation);
00234          if (NT_SUCCESS(Status) && (EaInformation.EaSize != 0))
00235          {
00236             /* there's extended attributes to read, let's give it a try */
00237             EaBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
00238                                        0,
00239                                        EaInformation.EaSize);
00240             if (EaBuffer == NULL)
00241             {
00242                RtlFreeHeap(RtlGetProcessHeap(),
00243                            0,
00244                            NtPathU.Buffer);
00245 
00246                /* the template file handle is valid and has extended attributes,
00247                   however we seem to lack some memory here. We should fail here! */
00248                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00249                return INVALID_HANDLE_VALUE;
00250             }
00251 
00252             Status = NtQueryEaFile(hTemplateFile,
00253                                    &IoStatusBlock,
00254                                    EaBuffer,
00255                                    EaInformation.EaSize,
00256                                    FALSE,
00257                                    NULL,
00258                                    0,
00259                                    NULL,
00260                                    TRUE);
00261 
00262             if (NT_SUCCESS(Status))
00263             {
00264                /* we successfully read the extended attributes, break the loop
00265                   and continue */
00266                EaLength = EaInformation.EaSize;
00267                break;
00268             }
00269             else
00270             {
00271                RtlFreeHeap(RtlGetProcessHeap(),
00272                            0,
00273                            EaBuffer);
00274                EaBuffer = NULL;
00275 
00276                if (Status != STATUS_BUFFER_TOO_SMALL)
00277                {
00278                   /* unless we just allocated not enough memory, break the loop
00279                      and just continue without copying extended attributes */
00280                   break;
00281                }
00282             }
00283          }
00284          else
00285          {
00286             /* we either failed to get the size of the extended attributes or
00287                they're empty, just continue as there's no need to copy
00288                attributes */
00289             break;
00290          }
00291       }
00292    }
00293 
00294    /* build the object attributes */
00295    InitializeObjectAttributes(&ObjectAttributes,
00296                               &NtPathU,
00297                               0,
00298                               NULL,
00299                               NULL);
00300 
00301    if (lpSecurityAttributes)
00302    {
00303       if(lpSecurityAttributes->bInheritHandle)
00304          ObjectAttributes.Attributes |= OBJ_INHERIT;
00305 
00306       ObjectAttributes.SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
00307    }
00308 
00309    if(!(dwFlagsAndAttributes & FILE_FLAG_POSIX_SEMANTICS))
00310     ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
00311 
00312    /* perform the call */
00313    Status = NtCreateFile (&FileHandle,
00314               dwDesiredAccess,
00315               &ObjectAttributes,
00316               &IoStatusBlock,
00317               NULL,
00318               FileAttributes,
00319               dwShareMode,
00320               dwCreationDisposition,
00321               Flags,
00322               EaBuffer,
00323               EaLength);
00324 
00325    RtlFreeHeap(RtlGetProcessHeap(),
00326                0,
00327                NtPathU.Buffer);
00328 
00329    /* free the extended attributes buffer if allocated */
00330    if (EaBuffer != NULL)
00331    {
00332       RtlFreeHeap(RtlGetProcessHeap(),
00333                   0,
00334                   EaBuffer);
00335    }
00336 
00337    /* error */
00338    if (!NT_SUCCESS(Status))
00339    {
00340       /* In the case file creation was rejected due to CREATE_NEW flag
00341        * was specified and file with that name already exists, correct
00342        * last error is ERROR_FILE_EXISTS and not ERROR_ALREADY_EXISTS.
00343        * Note: RtlNtStatusToDosError is not the subject to blame here.
00344        */
00345       if (Status == STATUS_OBJECT_NAME_COLLISION &&
00346           dwCreationDisposition == FILE_CREATE)
00347       {
00348          SetLastError( ERROR_FILE_EXISTS );
00349       }
00350       else
00351       {
00352          BaseSetLastNTError (Status);
00353       }
00354 
00355       return INVALID_HANDLE_VALUE;
00356    }
00357 
00358   /*
00359   create with OPEN_ALWAYS (FILE_OPEN_IF) returns info = FILE_OPENED or FILE_CREATED
00360   create with CREATE_ALWAYS (FILE_OVERWRITE_IF) returns info = FILE_OVERWRITTEN or FILE_CREATED
00361   */
00362   if (dwCreationDisposition == FILE_OPEN_IF)
00363   {
00364     SetLastError(IoStatusBlock.Information == FILE_OPENED ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
00365   }
00366   else if (dwCreationDisposition == FILE_OVERWRITE_IF)
00367   {
00368     SetLastError(IoStatusBlock.Information == FILE_OVERWRITTEN ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
00369   }
00370   else
00371   {
00372     SetLastError(ERROR_SUCCESS);
00373   }
00374 
00375   return FileHandle;
00376 }
00377 
00378 /*
00379  * @implemented
00380  */
00381 HFILE WINAPI
00382 OpenFile(LPCSTR lpFileName,
00383      LPOFSTRUCT lpReOpenBuff,
00384      UINT uStyle)
00385 {
00386     OBJECT_ATTRIBUTES ObjectAttributes;
00387     IO_STATUS_BLOCK IoStatusBlock;
00388     UNICODE_STRING FileNameString;
00389     UNICODE_STRING FileNameU;
00390     ANSI_STRING FileName;
00391     WCHAR PathNameW[MAX_PATH];
00392     HANDLE FileHandle = NULL;
00393     NTSTATUS errCode;
00394     PWCHAR FilePart;
00395     ULONG Len;
00396 
00397     TRACE("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName, lpReOpenBuff, uStyle);
00398 
00399     if (lpReOpenBuff == NULL)
00400     {
00401         return HFILE_ERROR;
00402     }
00403 
00404     lpReOpenBuff->nErrCode = 0;
00405 
00406     if (uStyle & OF_REOPEN) lpFileName = lpReOpenBuff->szPathName;
00407 
00408     if (!lpFileName)
00409     {
00410         return HFILE_ERROR;
00411     }
00412 
00413     if (!GetFullPathNameA(lpFileName,
00414                           sizeof(lpReOpenBuff->szPathName),
00415                           lpReOpenBuff->szPathName,
00416                           NULL))
00417     {
00418         lpReOpenBuff->nErrCode = GetLastError();
00419         return HFILE_ERROR;
00420     }
00421 
00422     if (uStyle & OF_PARSE)
00423     {
00424         lpReOpenBuff->fFixedDisk = (GetDriveTypeA(lpReOpenBuff->szPathName) != DRIVE_REMOVABLE);
00425         TRACE("(%s): OF_PARSE, res = '%s'\n", lpFileName, lpReOpenBuff->szPathName);
00426         return 0;
00427     }
00428 
00429     if ((uStyle & OF_EXIST) && !(uStyle & OF_CREATE))
00430     {
00431         DWORD dwAttributes = GetFileAttributesA(lpReOpenBuff->szPathName);
00432 
00433         switch (dwAttributes)
00434         {
00435             case 0xFFFFFFFF: /* File does not exist */
00436                 SetLastError(ERROR_FILE_NOT_FOUND);
00437                 lpReOpenBuff->nErrCode = (WORD) ERROR_FILE_NOT_FOUND;
00438                 return -1;
00439 
00440             case FILE_ATTRIBUTE_DIRECTORY:
00441                 SetLastError(ERROR_ACCESS_DENIED);
00442                 lpReOpenBuff->nErrCode = (WORD) ERROR_ACCESS_DENIED;
00443                 return -1;
00444 
00445             default:
00446                 lpReOpenBuff->cBytes = sizeof(OFSTRUCT);
00447                 return 1;
00448         }
00449     }
00450     lpReOpenBuff->cBytes = sizeof(OFSTRUCT);
00451     if ((uStyle & OF_CREATE) == OF_CREATE)
00452     {
00453         DWORD Sharing;
00454         switch (uStyle & 0x70)
00455         {
00456             case OF_SHARE_EXCLUSIVE: Sharing = 0; break;
00457             case OF_SHARE_DENY_WRITE: Sharing = FILE_SHARE_READ; break;
00458             case OF_SHARE_DENY_READ: Sharing = FILE_SHARE_WRITE; break;
00459             case OF_SHARE_DENY_NONE:
00460             case OF_SHARE_COMPAT:
00461             default:
00462                 Sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
00463         }
00464         return (HFILE) CreateFileA (lpFileName,
00465                                     GENERIC_READ | GENERIC_WRITE,
00466                                     Sharing,
00467                                     NULL,
00468                                     CREATE_ALWAYS,
00469                                     FILE_ATTRIBUTE_NORMAL,
00470                                     0);
00471     }
00472 
00473     RtlInitAnsiString (&FileName, (LPSTR)lpFileName);
00474 
00475     /* convert ansi (or oem) string to unicode */
00476     if (bIsFileApiAnsi)
00477         RtlAnsiStringToUnicodeString (&FileNameU, &FileName, TRUE);
00478     else
00479         RtlOemStringToUnicodeString (&FileNameU, &FileName, TRUE);
00480 
00481     Len = SearchPathW (NULL,
00482                        FileNameU.Buffer,
00483                        NULL,
00484                        OFS_MAXPATHNAME,
00485                        PathNameW,
00486                        &FilePart);
00487 
00488     RtlFreeUnicodeString(&FileNameU);
00489 
00490     if (Len == 0 || Len > OFS_MAXPATHNAME)
00491     {
00492         lpReOpenBuff->nErrCode = GetLastError();
00493         return (HFILE)INVALID_HANDLE_VALUE;
00494     }
00495 
00496     if (uStyle & OF_DELETE)
00497     {
00498         if (!DeleteFileW(PathNameW))
00499         {
00500             lpReOpenBuff->nErrCode = GetLastError();
00501             return HFILE_ERROR;
00502         }
00503         TRACE("(%s): OF_DELETE return = OK\n", lpFileName);
00504         return TRUE;
00505     }
00506 
00507     FileName.Buffer = lpReOpenBuff->szPathName;
00508     FileName.Length = 0;
00509     FileName.MaximumLength = OFS_MAXPATHNAME;
00510 
00511     RtlInitUnicodeString(&FileNameU, PathNameW);
00512 
00513     /* convert unicode string to ansi (or oem) */
00514     if (bIsFileApiAnsi)
00515         RtlUnicodeStringToAnsiString (&FileName, &FileNameU, FALSE);
00516     else
00517         RtlUnicodeStringToOemString (&FileName, &FileNameU, FALSE);
00518 
00519     if (!RtlDosPathNameToNtPathName_U (PathNameW,
00520                        &FileNameString,
00521                        NULL,
00522                        NULL))
00523     {
00524         return (HFILE)INVALID_HANDLE_VALUE;
00525     }
00526 
00527     // FILE_SHARE_READ
00528     // FILE_NO_INTERMEDIATE_BUFFERING
00529 
00530     ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
00531     ObjectAttributes.RootDirectory = NULL;
00532     ObjectAttributes.ObjectName = &FileNameString;
00533     ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
00534     ObjectAttributes.SecurityDescriptor = NULL;
00535     ObjectAttributes.SecurityQualityOfService = NULL;
00536 
00537     errCode = NtOpenFile (&FileHandle,
00538                           GENERIC_READ|SYNCHRONIZE,
00539                           &ObjectAttributes,
00540                           &IoStatusBlock,
00541                           FILE_SHARE_READ,
00542                           FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);
00543 
00544     RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameString.Buffer);
00545 
00546     lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
00547 
00548     if (!NT_SUCCESS(errCode))
00549     {
00550         BaseSetLastNTError (errCode);
00551         return (HFILE)INVALID_HANDLE_VALUE;
00552     }
00553 
00554     if (uStyle & OF_EXIST)
00555     {
00556         NtClose(FileHandle);
00557         return (HFILE)1;
00558     }
00559 
00560     return (HFILE)FileHandle;
00561 }
00562 
00563 /*
00564  * @unimplemented
00565  */
00566 BOOL
00567 WINAPI
00568 OpenDataFile(HANDLE hFile, DWORD dwUnused)
00569 {
00570     STUB;
00571     return FALSE;
00572 }
00573 
00574 /*
00575  * @unimplemented
00576  */
00577 HANDLE
00578 WINAPI
00579 ReOpenFile(IN HANDLE hOriginalFile,
00580            IN DWORD dwDesiredAccess,
00581            IN DWORD dwShareMode,
00582            IN DWORD dwFlags)
00583 {
00584    STUB;
00585    return INVALID_HANDLE_VALUE;
00586 }
00587 
00588 /* EOF */

Generated on Sun May 27 2012 04:16:58 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.