2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis, Sven Verdoolaege, and Cameron Heide
10 #include <sys/types.h>
29 static void UnixTimeToFileTime(time_t unix_time
, FILETIME
*filetime
);
30 static int TranslateCreationFlags(DWORD create_flags
);
31 static int TranslateAccessFlags(DWORD access_flags
);
32 int TranslateProtectionFlags(DWORD
);
37 /***********************************************************************
38 * OpenFileMappingA (KERNEL32.397)
42 HANDLE32
OpenFileMapping(DWORD access
, BOOL inherit
,const char *fname
)
48 /***********************************************************************
49 * CreateFileMapping32A (KERNEL32.46)
51 HANDLE32
CreateFileMapping32A(HANDLE32 h
,LPSECURITY_ATTRIBUTES ats
,
52 DWORD pot
, DWORD sh
, DWORD hlow
, LPCSTR lpName
)
55 FILEMAP_OBJECT
*filemap_obj
;
58 SetLastError(ErrnoToLastError(errno
));
59 return INVALID_HANDLE_VALUE
;
61 hfile
= _lcreat(lpName
,1);
62 if(hfile
== HFILE_ERROR
) {
63 SetLastError(ErrnoToLastError(errno
));
64 return INVALID_HANDLE_VALUE
;
66 filemap_obj
=(FILEMAP_OBJECT
*)CreateKernelObject(sizeof(FILEMAP_OBJECT
));
67 if(filemap_obj
== NULL
) {
69 SetLastError(ERROR_UNKNOWN
);
73 filemap_obj
->common
.magic
= KERNEL_OBJECT_FILEMAP
;
74 filemap_obj
->hfile
= hfile
;
75 filemap_obj
->prot
= TranslateProtectionFlags(pot
);
76 filemap_obj
->size
= hlow
;
77 return (HANDLE32
)filemap_obj
;;
80 /***********************************************************************
81 * CreateFileMapping32W (KERNEL32.47)
84 HANDLE32
CreateFileMapping32W(HANDLE32 h
,LPSECURITY_ATTRIBUTES ats
,
85 DWORD pot
, DWORD sh
, DWORD hlow
, LPCWSTR lpName
)
88 LPSTR aname
= STRING32_DupUniToAnsi(lpName
);
90 res
= CreateFileMapping32A(h
,ats
,pot
,sh
,hlow
,aname
);
96 /***********************************************************************
97 * MapViewOfFileEx (KERNEL32.386)
100 LPVOID
MapViewOfFileEx(HANDLE32 handle
, DWORD access
, DWORD offhi
,
101 DWORD offlo
, DWORD size
, DWORD st
)
103 if (!size
) size
= ((FILEMAP_OBJECT
*)handle
)->size
;
104 return mmap ((caddr_t
)st
, size
, ((FILEMAP_OBJECT
*)handle
)->prot
,
105 MAP_ANON
|MAP_PRIVATE
,
106 FILE_GetUnixHandle(((FILEMAP_OBJECT
*)handle
)->hfile
),
111 /***********************************************************************
112 * GetFileInformationByHandle (KERNEL32.219)
114 DWORD
GetFileInformationByHandle(HFILE hFile
,BY_HANDLE_FILE_INFORMATION
*lpfi
)
116 struct stat file_stat
;
118 int unixfd
= FILE_GetUnixHandle(hFile
);
122 rc
= fstat(unixfd
,&file_stat
);
124 SetLastError(ErrnoToLastError(errno
));
128 /* Translate the file attributes.
130 lpfi
->dwFileAttributes
= 0;
131 if(file_stat
.st_mode
& S_IFREG
)
132 lpfi
->dwFileAttributes
|= FILE_ATTRIBUTE_NORMAL
;
133 if(file_stat
.st_mode
& S_IFDIR
)
134 lpfi
->dwFileAttributes
|= FILE_ATTRIBUTE_DIRECTORY
;
135 if((file_stat
.st_mode
& S_IWRITE
) == 0)
136 lpfi
->dwFileAttributes
|= FILE_ATTRIBUTE_READONLY
;
138 /* Translate the file times. Use the last modification time
139 * for both the creation time and write time.
141 UnixTimeToFileTime(file_stat
.st_mtime
, &(lpfi
->ftCreationTime
));
142 UnixTimeToFileTime(file_stat
.st_mtime
, &(lpfi
->ftLastWriteTime
));
143 UnixTimeToFileTime(file_stat
.st_atime
, &(lpfi
->ftLastAccessTime
));
145 lpfi
->nFileSizeLow
= file_stat
.st_size
;
146 lpfi
->nNumberOfLinks
= file_stat
.st_nlink
;
147 lpfi
->nFileIndexLow
= file_stat
.st_ino
;
149 /* Zero out currently unused fields.
151 lpfi
->dwVolumeSerialNumber
= 0;
152 lpfi
->nFileSizeHigh
= 0;
153 lpfi
->nFileIndexHigh
= 0;
158 static void UnixTimeToFileTime(time_t unix_time
, FILETIME
*filetime
)
160 /* This isn't anywhere close to being correct, but should
163 filetime
->dwLowDateTime
= (unix_time
& 0x0000FFFF) << 16;
164 filetime
->dwHighDateTime
= (unix_time
& 0xFFFF0000) >> 16;
167 time_t FileTimeToUnixTime(FILETIME
*filetime
)
169 /* reverse of UnixTimeToFileTime */
170 return (filetime
->dwLowDateTime
>>16)+(filetime
->dwHighDateTime
<<16);
173 /***********************************************************************
174 * GetStdHandle (KERNEL32.276)
175 * FIXME: We should probably allocate filehandles for stdin/stdout/stderr
176 * at task creation (with HFILE-handle 0,1,2 respectively) and
177 * return them here. Or at least look, if we created them already.
179 HFILE
GetStdHandle(DWORD nStdHandle
)
186 case STD_INPUT_HANDLE
:
190 case STD_OUTPUT_HANDLE
:
194 case STD_ERROR_HANDLE
:
198 SetLastError(ERROR_INVALID_HANDLE
);
201 hfile
= FILE_DupUnixHandle(unixfd
);
202 if (hfile
== HFILE_ERROR
)
204 FILE_SetFileType( hfile
, FILE_TYPE_CHAR
);
209 /***********************************************************************
210 * SetFilePointer (KERNEL32.492)
212 * Luckily enough, this function maps almost directly into an lseek
213 * call, the exception being the use of 64-bit offsets.
215 DWORD
SetFilePointer(HFILE hFile
, LONG distance
, LONG
*highword
,
223 dprintf_file(stddeb
, "SetFilePointer: 64-bit offsets not yet supported.\n");
228 rc
= _llseek(hFile
, distance
, method
);
230 SetLastError(ErrnoToLastError(errno
));
234 /***********************************************************************
235 * WriteFile (KERNEL32.578)
237 BOOL32
WriteFile(HFILE hFile
, LPVOID lpBuffer
, DWORD numberOfBytesToWrite
,
238 LPDWORD numberOfBytesWritten
, LPOVERLAPPED lpOverlapped
)
242 res
= _lwrite32(hFile
,lpBuffer
,numberOfBytesToWrite
);
244 SetLastError(ErrnoToLastError(errno
));
247 if(numberOfBytesWritten
)
248 *numberOfBytesWritten
= res
;
252 /***********************************************************************
253 * ReadFile (KERNEL32.428)
255 BOOL32
ReadFile(HFILE hFile
, LPVOID lpBuffer
, DWORD numtoread
,
256 LPDWORD numread
, LPOVERLAPPED lpOverlapped
)
260 actual_read
= _lread32(hFile
,lpBuffer
,numtoread
);
261 if(actual_read
== -1) {
262 SetLastError(ErrnoToLastError(errno
));
266 *numread
= actual_read
;
272 /*************************************************************************
273 * CreateFile32A (KERNEL32.45)
275 * Doesn't support character devices, pipes, template files, or a
276 * lot of the 'attributes' flags yet.
278 HFILE
CreateFile32A(LPCSTR filename
, DWORD access
, DWORD sharing
,
279 LPSECURITY_ATTRIBUTES security
, DWORD creation
,
280 DWORD attributes
, HANDLE32
template)
282 int access_flags
, create_flags
;
284 /* Translate the various flags to Unix-style.
286 access_flags
= TranslateAccessFlags(access
);
287 create_flags
= TranslateCreationFlags(creation
);
290 dprintf_file(stddeb
, "CreateFile: template handles not supported.\n");
292 /* If the name starts with '\\?' or '\\.', ignore the first 3 chars.
294 if(!strncmp(filename
, "\\\\?", 3) || !strncmp(filename
, "\\\\.", 3))
297 /* If the name still starts with '\\', it's a UNC name.
299 if(!strncmp(filename
, "\\\\", 2))
301 dprintf_file(stddeb
, "CreateFile: UNC names not supported.\n");
302 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
306 /* If the name is either CONIN$ or CONOUT$, give them stdin
307 * or stdout, respectively.
309 if(!strcmp(filename
, "CONIN$")) return GetStdHandle( STD_INPUT_HANDLE
);
310 if(!strcmp(filename
, "CONOUT$")) return GetStdHandle( STD_OUTPUT_HANDLE
);
312 return FILE_Open( filename
, access_flags
| create_flags
);
316 /*************************************************************************
317 * CreateFile32W (KERNEL32.48)
319 HFILE
CreateFile32W(LPCWSTR filename
, DWORD access
, DWORD sharing
,
320 LPSECURITY_ATTRIBUTES security
, DWORD creation
,
321 DWORD attributes
, HANDLE32
template)
324 LPSTR afn
= STRING32_DupUniToAnsi(filename
);
326 res
= CreateFile32A(afn
,access
,sharing
,security
,creation
,attributes
,template);
331 /*************************************************************************
332 * SetHandleCount32 (KERNEL32.494)
334 UINT32
SetHandleCount32( UINT32 cHandles
)
336 return SetHandleCount16(cHandles
);
340 int CloseFileHandle(HFILE hFile
)
347 static int TranslateAccessFlags(DWORD access_flags
)
361 case (GENERIC_READ
| GENERIC_WRITE
):
369 static int TranslateCreationFlags(DWORD create_flags
)
376 rc
= O_CREAT
| O_EXCL
;
380 rc
= O_CREAT
| O_TRUNC
;
391 case TRUNCATE_EXISTING
:
400 /**************************************************************************
401 * GetFileAttributes32A (KERNEL32.217)
403 DWORD
GetFileAttributes32A(LPCSTR lpFileName
)
409 dprintf_file(stddeb
,"GetFileAttributesA(%s)\n",lpFileName
);
410 fn
=(LPSTR
)DOSFS_GetUnixFileName(lpFileName
,FALSE
);
411 /* fn points to a static buffer, don't free it */
412 if(stat(fn
,&buf
)==-1) {
413 SetLastError(ErrnoToLastError(errno
));
416 if(buf
.st_mode
& S_IFREG
)
417 res
|= FILE_ATTRIBUTE_NORMAL
;
418 if(buf
.st_mode
& S_IFDIR
)
419 res
|= FILE_ATTRIBUTE_DIRECTORY
;
420 if((buf
.st_mode
& S_IWRITE
) == 0)
421 res
|= FILE_ATTRIBUTE_READONLY
;
425 /**************************************************************************
426 * GetFileAttributes32W (KERNEL32.218)
428 DWORD
GetFileAttributes32W(LPCWSTR lpFileName
)
430 LPSTR afn
= STRING32_DupUniToAnsi(lpFileName
);
433 res
= GetFileAttributes32A(afn
);
439 /**************************************************************************
440 * SetFileAttributes32A (KERNEL32.490)
442 BOOL32
SetFileAttributes32A(LPCSTR lpFileName
, DWORD attributes
)
445 LPSTR fn
=(LPSTR
)DOSFS_GetUnixFileName(lpFileName
,FALSE
);
447 dprintf_file(stddeb
,"SetFileAttributes(%s,%lx)\n",lpFileName
,attributes
);
448 if(stat(fn
,&buf
)==-1) {
449 SetLastError(ErrnoToLastError(errno
));
452 if (attributes
& FILE_ATTRIBUTE_READONLY
) {
453 buf
.st_mode
&= ~0222; /* octal!, clear write permission bits */
454 attributes
&= ~FILE_ATTRIBUTE_READONLY
;
456 attributes
&= ~(FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
);
458 fprintf(stdnimp
,"SetFileAttributesA(%s):%lx attribute(s) not implemented.\n",lpFileName
,attributes
);
459 if (-1==chmod(fn
,buf
.st_mode
)) {
460 SetLastError(ErrnoToLastError(errno
));
466 /**************************************************************************
467 * SetFileAttributes32W (KERNEL32.491)
469 BOOL32
SetFileAttributes32W(LPCWSTR lpFileName
, DWORD attributes
)
471 LPSTR afn
= STRING32_DupUniToAnsi(lpFileName
);
474 res
= SetFileAttributes32A(afn
,attributes
);
479 /**************************************************************************
480 * SetEndOfFile (KERNEL32.483)
482 BOOL32
SetEndOfFile(HFILE hFile
)
484 int unixfd
= FILE_GetUnixHandle(hFile
);
486 dprintf_file(stddeb
,"SetEndOfFile(%lx)\n",(LONG
)hFile
);
489 if (-1==ftruncate(unixfd
,lseek(unixfd
,0,SEEK_CUR
))) {
490 SetLastError(ErrnoToLastError(errno
));
497 /**************************************************************************
498 * MoveFileA (KERNEL32.387)
500 BOOL32
MoveFile32A(LPCSTR fn1
,LPCSTR fn2
)
505 dprintf_file(stddeb
,"MoveFileA(%s,%s)\n",fn1
,fn2
);
506 ufn1
= (LPSTR
)DOSFS_GetUnixFileName(fn1
,FALSE
);
508 SetLastError(ErrnoToLastError(ENOENT
));
511 ufn1
= xstrdup(ufn1
);
512 ufn2
= (LPSTR
)DOSFS_GetUnixFileName(fn2
,FALSE
);
514 SetLastError(ErrnoToLastError(ENOENT
));
517 ufn2
= xstrdup(ufn2
);
518 if (-1==rename(ufn1
,ufn2
)) {
519 SetLastError(ErrnoToLastError(errno
));
529 /**************************************************************************
530 * MoveFileW (KERNEL32.390)
532 BOOL32
MoveFile32W(LPCWSTR fn1
,LPCWSTR fn2
)
534 LPSTR afn1
= STRING32_DupUniToAnsi(fn1
);
535 LPSTR afn2
= STRING32_DupUniToAnsi(fn2
);
538 res
= MoveFile32A(afn1
,afn2
);