2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis, Sven Verdoolaege, and Cameron Heide
10 #include <sys/types.h>
26 extern FILE_OBJECT *hstdin;
27 extern FILE_OBJECT *hstdout;
28 extern FILE_OBJECT *hstderr;
30 static void UnixTimeToFileTime(time_t unix_time, FILETIME *filetime);
31 static int TranslateCreationFlags(DWORD create_flags);
32 static int TranslateAccessFlags(DWORD access_flags);
37 /***********************************************************************
38 * OpenFileMappingA (KERNEL32.397)
41 WINAPI HANDLE32 OpenFileMapping(DWORD access, BOOL inherit,const char *fname)
45 /***********************************************************************
46 * CreateFileMappingA (KERNEL32.46)
49 int TranslateProtectionFlags(DWORD);
50 WINAPI HANDLE32 CreateFileMapping(HANDLE32 h,SECURITY_ATTRIBUTES *ats,
51 DWORD pot, DWORD sh, DWORD hlow, const char * lpName )
53 FILE_OBJECT *file_obj;
54 FILEMAP_OBJECT *filemap_obj;
59 SetLastError(ErrnoToLastError(errno));
60 return INVALID_HANDLE_VALUE;
62 fd = open(lpName, O_CREAT, 0666);
65 SetLastError(ErrnoToLastError(errno));
66 return INVALID_HANDLE_VALUE;
68 file_obj = (FILE_OBJECT *)
69 CreateKernelObject(sizeof(FILE_OBJECT));
72 SetLastError(ERROR_UNKNOWN);
75 filemap_obj = (FILEMAP_OBJECT *)
76 CreateKernelObject(sizeof(FILEMAP_OBJECT));
77 if(filemap_obj == NULL)
79 ReleaseKernelObject(file_obj);
80 SetLastError(ERROR_UNKNOWN);
83 file_obj->common.magic = KERNEL_OBJECT_FILE;
85 file_obj->type = FILE_TYPE_DISK;
86 filemap_obj->common.magic = KERNEL_OBJECT_FILEMAP;
87 filemap_obj->file_obj = file_obj;
88 filemap_obj->prot = TranslateProtectionFlags(pot);
89 filemap_obj->size = hlow;
90 return (HANDLE32)filemap_obj;;
93 /***********************************************************************
94 * MapViewOfFileEx (KERNEL32.386)
97 WINAPI void *MapViewOfFileEx(HANDLE32 handle, DWORD access, DWORD offhi,
98 DWORD offlo, DWORD size, DWORD st)
100 if (!size) size = ((FILEMAP_OBJECT *)handle)->size;
101 return mmap ((caddr_t)st, size, ((FILEMAP_OBJECT *)handle)->prot,
102 MAP_ANON|MAP_PRIVATE,
103 ((FILEMAP_OBJECT *)handle)->file_obj->fd,
107 /***********************************************************************
108 * GetFileInformationByHandle (KERNEL32.219)
111 DWORD WINAPI GetFileInformationByHandle(FILE_OBJECT *hFile,
112 BY_HANDLE_FILE_INFORMATION *lpfi)
114 struct stat file_stat;
117 if(ValidateKernelObject((HANDLE32)hFile) != 0)
119 SetLastError(ERROR_INVALID_HANDLE);
122 if(hFile->common.magic != KERNEL_OBJECT_FILE)
124 SetLastError(ERROR_INVALID_HANDLE);
128 rc = fstat(hFile->fd, &file_stat);
131 SetLastError(ErrnoToLastError(errno));
135 /* Translate the file attributes.
137 lpfi->dwFileAttributes = 0;
138 if(file_stat.st_mode & S_IFREG)
139 lpfi->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL;
140 if(file_stat.st_mode & S_IFDIR)
141 lpfi->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
142 if((file_stat.st_mode & S_IWRITE) == 0)
143 lpfi->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
145 /* Translate the file times. Use the last modification time
146 * for both the creation time and write time.
148 UnixTimeToFileTime(file_stat.st_mtime, &(lpfi->ftCreationTime));
149 UnixTimeToFileTime(file_stat.st_mtime, &(lpfi->ftLastWriteTime));
150 UnixTimeToFileTime(file_stat.st_atime, &(lpfi->ftLastAccessTime));
152 lpfi->nFileSizeLow = file_stat.st_size;
153 lpfi->nNumberOfLinks = file_stat.st_nlink;
154 lpfi->nFileIndexLow = file_stat.st_ino;
156 /* Zero out currently unused fields.
158 lpfi->dwVolumeSerialNumber = 0;
159 lpfi->nFileSizeHigh = 0;
160 lpfi->nFileIndexHigh = 0;
166 static void UnixTimeToFileTime(time_t unix_time, FILETIME *filetime)
168 /* This isn't anywhere close to being correct, but should
171 filetime->dwLowDateTime = (unix_time & 0x0000FFFF) << 16;
172 filetime->dwHighDateTime = (unix_time & 0xFFFF0000) >> 16;
176 /***********************************************************************
177 * GetFileType (KERNEL32.222)
179 * GetFileType currently only supports stdin, stdout, and stderr, which
180 * are considered to be of type FILE_TYPE_CHAR.
182 DWORD GetFileType(FILE_OBJECT *hFile)
184 if(ValidateKernelObject((HANDLE32)hFile) != 0)
186 SetLastError(ERROR_UNKNOWN);
187 return FILE_TYPE_UNKNOWN;
189 if(hFile->common.magic != KERNEL_OBJECT_FILE)
191 SetLastError(ERROR_UNKNOWN);
192 return FILE_TYPE_UNKNOWN;
198 /***********************************************************************
199 * GetStdHandle (KERNEL32.276)
201 HANDLE32 GetStdHandle(DWORD nStdHandle)
207 case STD_INPUT_HANDLE:
208 rc = (HANDLE32)hstdin;
211 case STD_OUTPUT_HANDLE:
212 rc = (HANDLE32)hstdout;
215 case STD_ERROR_HANDLE:
216 rc = (HANDLE32)hstderr;
220 rc = INVALID_HANDLE_VALUE;
221 SetLastError(ERROR_INVALID_HANDLE);
228 /***********************************************************************
229 * SetFilePointer (KERNEL32.492)
231 * Luckily enough, this function maps almost directly into an lseek
232 * call, the exception being the use of 64-bit offsets.
234 DWORD SetFilePointer(FILE_OBJECT *hFile, LONG distance, LONG *highword,
239 if(ValidateKernelObject((HANDLE32)hFile) != 0)
241 SetLastError(ERROR_INVALID_HANDLE);
242 return ((DWORD)0xFFFFFFFF);
244 if(hFile->common.magic != KERNEL_OBJECT_FILE)
246 SetLastError(ERROR_INVALID_HANDLE);
247 return ((DWORD)0xFFFFFFFF);
254 dprintf_win32(stddeb, "SetFilePointer: 64-bit offsets not yet supported.\n");
259 rc = lseek(hFile->fd, distance, method);
261 SetLastError(ErrnoToLastError(errno));
265 /***********************************************************************
266 * WriteFile (KERNEL32.578)
268 BOOL WriteFile(FILE_OBJECT *hFile, LPVOID lpBuffer, DWORD numberOfBytesToWrite,
269 LPDWORD numberOfBytesWritten, LPOVERLAPPED lpOverlapped)
273 if(ValidateKernelObject((HANDLE32)hFile) != 0)
275 SetLastError(ERROR_INVALID_HANDLE);
278 if(hFile->common.magic != KERNEL_OBJECT_FILE)
280 SetLastError(ERROR_INVALID_HANDLE);
284 written = write(hFile->fd, lpBuffer, numberOfBytesToWrite);
285 if(numberOfBytesWritten)
286 *numberOfBytesWritten = written;
291 /***********************************************************************
292 * ReadFile (KERNEL32.428)
294 BOOL ReadFile(FILE_OBJECT *hFile, LPVOID lpBuffer, DWORD numtoread,
295 LPDWORD numread, LPOVERLAPPED lpOverlapped)
299 if(ValidateKernelObject((HANDLE32)hFile) != 0)
301 SetLastError(ERROR_INVALID_HANDLE);
304 if(hFile->common.magic != KERNEL_OBJECT_FILE)
306 SetLastError(ERROR_INVALID_HANDLE);
310 actual_read = read(hFile->fd, lpBuffer, numtoread);
311 if(actual_read == -1)
313 SetLastError(ErrnoToLastError(errno));
317 *numread = actual_read;
322 /*************************************************************************
323 * CreateFile (KERNEL32.45)
325 * Doesn't support character devices, pipes, template files, or a
326 * lot of the 'attributes' flags yet.
328 HANDLE32 CreateFileA(LPSTR filename, DWORD access, DWORD sharing,
329 LPSECURITY_ATTRIBUTES security, DWORD creation,
330 DWORD attributes, HANDLE32 template)
332 int access_flags, create_flags;
334 FILE_OBJECT *file_obj;
337 /* Translate the various flags to Unix-style.
339 access_flags = TranslateAccessFlags(access);
340 create_flags = TranslateCreationFlags(creation);
343 dprintf_win32(stddeb, "CreateFile: template handles not supported.\n");
345 /* If the name starts with '\\?' or '\\.', ignore the first 3 chars.
347 if(!strncmp(filename, "\\\\?", 3) || !strncmp(filename, "\\\\.", 3))
350 /* If the name still starts with '\\', it's a UNC name.
352 if(!strncmp(filename, "\\\\", 2))
354 dprintf_win32(stddeb, "CreateFile: UNC names not supported.\n");
355 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
356 return INVALID_HANDLE_VALUE;
359 /* If the name is either CONIN$ or CONOUT$, give them stdin
360 * or stdout, respectively.
362 if(!strcmp(filename, "CONIN$"))
364 type = FILE_TYPE_CHAR;
367 else if(!strcmp(filename, "CONOUT$"))
369 type = FILE_TYPE_CHAR;
374 const char *unixName = DOSFS_GetUnixFileName( filename, FALSE );
375 type = FILE_TYPE_DISK;
377 /* Try to open the file.
380 ((fd = open(unixName, access_flags | create_flags, 0666)) == -1))
382 SetLastError(ErrnoToLastError(errno));
383 return INVALID_HANDLE_VALUE;
387 /* We seem to have succeeded, so allocate a kernel object
390 file_obj = (FILE_OBJECT *)CreateKernelObject(sizeof(FILE_OBJECT));
393 SetLastError(ERROR_INVALID_HANDLE);
394 return INVALID_HANDLE_VALUE;
396 file_obj->common.magic = KERNEL_OBJECT_FILE;
398 file_obj->type = type;
399 file_obj->misc_flags = attributes;
400 file_obj->access_flags = access_flags;
401 file_obj->create_flags = create_flags;
403 return (HANDLE32)file_obj;
406 /*************************************************************************
407 * W32_SetHandleCount (KERNEL32.??)
410 UINT W32_SetHandleCount(UINT cHandles)
412 return SetHandleCount(cHandles);
415 int CloseFileHandle(FILE_OBJECT *hFile)
417 /* If it's one of the 3 standard handles, don't really
426 static int TranslateAccessFlags(DWORD access_flags)
440 case (GENERIC_READ | GENERIC_WRITE):
448 static int TranslateCreationFlags(DWORD create_flags)
455 rc = O_CREAT | O_EXCL;
459 rc = O_CREAT | O_TRUNC;
470 case TRUNCATE_EXISTING: