Fixed some embarassing errors
[reactos.git] / posix / lib / psxdll / fcntl / open.c
1 /* $Id: open.c,v 1.3 2002/05/17 01:54:39 hyperion Exp $
2 */
3 /*
4 * COPYRIGHT: See COPYING in the top level directory
5 * PROJECT: ReactOS POSIX+ Subsystem
6 * FILE: subsys/psx/lib/psxdll/fcntl/open.c
7 * PURPOSE: Open a file
8 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
9 * UPDATE HISTORY:
10 * 04/02/2002: Created
11 */
12
13 #include <ddk/ntddk.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <stdlib.h>
18 #include <stdarg.h>
19 #include <string.h>
20 #include <psx/path.h>
21 #include <psx/debug.h>
22 #include <psx/errno.h>
23 #include <psx/pdata.h>
24
25 int open(const char *path, int oflag, ...)
26 {
27 ANSI_STRING strPath;
28 UNICODE_STRING wstrPath;
29 int nRetVal;
30
31 RtlInitAnsiString(&strPath, (PCSZ)path);
32 RtlAnsiStringToUnicodeString(&wstrPath, &strPath, TRUE);
33
34 nRetVal = _Wopen(wstrPath.Buffer, oflag);
35
36 RtlFreeUnicodeString(&wstrPath);
37
38 return (nRetVal);
39 }
40
41 int _Wopen(const wchar_t *path, int oflag, ...)
42 {
43 OBJECT_ATTRIBUTES oaFileAttribs;
44 IO_STATUS_BLOCK isbStatus;
45 UNICODE_STRING wstrNativePath;
46 NTSTATUS nErrCode;
47 ULONG nDesiredAccess;
48 ULONG nCreateDisposition;
49 ULONG nCreateOptions;
50 HANDLE hFile;
51 #if 0
52 mode_t mFileMode;
53 #endif
54 int nFileNo;
55 __fildes_t fdDescriptor;
56
57 /* translate file access flag */
58 switch(oflag & O_ACCMODE)
59 {
60 case O_RDONLY:
61 {
62 nDesiredAccess = FILE_READ_ACCESS;
63 nCreateOptions = 0;
64 break;
65 }
66
67 case O_WRONLY:
68 {
69 nDesiredAccess = FILE_WRITE_ACCESS;
70 nCreateOptions = FILE_NON_DIRECTORY_FILE; /* required by the specification */
71 break;
72 }
73
74 case O_RDWR:
75 {
76 nDesiredAccess = FILE_READ_ACCESS | FILE_WRITE_ACCESS;
77 nCreateOptions = FILE_NON_DIRECTORY_FILE; /* required by the specification */
78 break;
79 }
80
81 default:
82 {
83 errno = EINVAL;
84 return (-1);
85 }
86
87 }
88
89 /* miscellaneous flags */
90 if((oflag & _O_DIRFILE) == _O_DIRFILE)
91 nCreateOptions |= FILE_DIRECTORY_FILE;
92
93 /* creation disposition */
94 if((oflag & O_CREAT) == O_CREAT)
95 if((oflag & O_EXCL) == O_EXCL)
96 nCreateDisposition = FILE_CREATE; /* O_CREAT + O_EXCL: create file, fail if file exists */
97 else
98 nCreateDisposition = FILE_OPEN_IF; /* O_CREAT: open file, create if file doesn't exist */
99 else if((oflag & O_TRUNC) == O_TRUNC)
100 nCreateDisposition = FILE_OVERWRITE; /* O_TRUNC: truncate existing file */
101 else
102 nCreateDisposition = FILE_OPEN; /* normal: open file, fail if file doesn't exist */
103
104 /* lock the environment */
105 __PdxAcquirePdataLock();
106
107 /* convert the path into a native path */
108 if(!__PdxPosixPathNameToNtPathName((LPWSTR)path, __PdxGetNativePathBuffer(), __PdxGetCurDir(), NULL))
109 {
110 __PdxReleasePdataLock();
111 return (-1);
112 }
113
114 /* set file generic object attributes */
115 oaFileAttribs.Length = sizeof(oaFileAttribs);
116 oaFileAttribs.RootDirectory = __PdxGetRootHandle();
117 oaFileAttribs.ObjectName = &wstrNativePath;
118 oaFileAttribs.Attributes = OBJ_INHERIT; /* child processes inherit all file descriptors */
119 oaFileAttribs.SecurityDescriptor = NULL;
120 oaFileAttribs.SecurityQualityOfService = NULL;
121
122 /* open or create the file */
123 nErrCode = NtCreateFile
124 (
125 &hFile,
126 nDesiredAccess | SYNCHRONIZE,
127 &oaFileAttribs,
128 &isbStatus,
129 NULL,
130 0,
131 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
132 nCreateDisposition,
133 nCreateOptions | FILE_SYNCHRONOUS_IO_NONALERT,
134 NULL,
135 0
136 );
137
138 /* failure */
139 if(!NT_SUCCESS(nErrCode))
140 {
141 ERR("NtCreateFile() failed with status 0x%08X", nErrCode);
142 __PdxReleasePdataLock();
143 errno = __status_to_errno(nErrCode);
144 return (-1);
145 }
146
147 /* initialize descriptor constructor */
148 memset(&fdDescriptor, 0, sizeof(fdDescriptor));
149 fdDescriptor.FileHandle = hFile;
150 fdDescriptor.OpenFlags = oflag;
151
152 /* allocate a new file descriptor */
153 nFileNo = fcntl(0, F_NEWFD, &fdDescriptor);
154
155 /* unlock the environment */
156 __PdxReleasePdataLock();
157
158 /* could not allocate the file descriptor */
159 if(nFileNo < 0)
160 {
161 NtClose(hFile);
162 return (-1);
163 }
164
165 /* return the file number */
166 return (nFileNo);
167 }
168
169 int creat(const char *path, mode_t mode)
170 {
171 return (open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
172 }
173
174 int _Wcreat(const wchar_t *path, mode_t mode)
175 {
176 return (_Wopen(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
177 }
178
179 /* EOF */
180