2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis, Sven Verdoolaege, and Cameron Heide
10 #include <sys/types.h>
29 static int TranslateCreationFlags(DWORD create_flags
);
30 static int TranslateAccessFlags(DWORD access_flags
);
31 int TranslateProtectionFlags(DWORD
);
36 /***********************************************************************
37 * OpenFileMappingA (KERNEL32.397)
41 HANDLE32
OpenFileMapping(DWORD access
, BOOL inherit
,const char *fname
)
47 /***********************************************************************
48 * CreateFileMapping32A (KERNEL32.46)
50 HANDLE32
CreateFileMapping32A(HANDLE32 h
,LPSECURITY_ATTRIBUTES ats
,
51 DWORD pot
, DWORD sh
, DWORD hlow
, LPCSTR lpName
)
53 FILEMAP_OBJECT
*filemap_obj
;
55 dprintf_win32(stddeb
,"CreateFileMapping32A(%08x,%p,%ld,%ld,%ld,%s)\n",
56 h
,ats
,pot
,sh
,hlow
,lpName
59 SetLastError(ErrnoToLastError(errno
));
60 return INVALID_HANDLE_VALUE
;
62 filemap_obj
=(FILEMAP_OBJECT
*)CreateKernelObject(sizeof(FILEMAP_OBJECT
));
63 if(filemap_obj
== NULL
) {
64 SetLastError(ERROR_UNKNOWN
);
67 if (h
==INVALID_HANDLE_VALUE
)
68 h
=_lcreat(lpName
,1);/*FIXME*/
70 filemap_obj
->common
.magic
= KERNEL_OBJECT_FILEMAP
;
71 filemap_obj
->hfile
= h
;
72 filemap_obj
->prot
= TranslateProtectionFlags(pot
);
73 filemap_obj
->size
= hlow
;
74 return (HANDLE32
)filemap_obj
;;
77 /***********************************************************************
78 * CreateFileMapping32W (KERNEL32.47)
81 HANDLE32
CreateFileMapping32W(HANDLE32 h
,LPSECURITY_ATTRIBUTES ats
,
82 DWORD pot
, DWORD sh
, DWORD hlow
, LPCWSTR lpName
)
84 LPSTR aname
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpName
);
85 HANDLE32 res
= CreateFileMapping32A(h
,ats
,pot
,sh
,hlow
,aname
);
86 HeapFree( GetProcessHeap(), 0, aname
);
91 /***********************************************************************
92 * MapViewOfFile (KERNEL32.385)
94 LPVOID
MapViewOfFile(HANDLE32 handle
, DWORD access
, DWORD offhi
,
95 DWORD offlo
, DWORD size
)
97 return MapViewOfFileEx(handle
,access
,offhi
,offlo
,size
,0);
100 /***********************************************************************
101 * MapViewOfFileEx (KERNEL32.386)
104 LPVOID
MapViewOfFileEx(HANDLE32 handle
, DWORD access
, DWORD offhi
,
105 DWORD offlo
, DWORD size
, DWORD st
)
107 FILEMAP_OBJECT
*fmap
= (FILEMAP_OBJECT
*)handle
;
109 if (!size
) size
= fmap
->size
;
111 return mmap ((caddr_t
)st
, size
, fmap
->prot
,
112 MAP_ANON
|MAP_PRIVATE
,
113 FILE_GetUnixHandle(fmap
->hfile
),
117 /***********************************************************************
118 * UnmapViewOfFile (KERNEL32.385)
120 BOOL32
UnmapViewOfFile(LPVOID address
) {
121 munmap(address
,/*hmm*/1); /* FIXME: size? */
127 /***********************************************************************
128 * GetFileInformationByHandle (KERNEL32.219)
130 DWORD
GetFileInformationByHandle(HFILE hFile
,BY_HANDLE_FILE_INFORMATION
*lpfi
)
132 struct stat file_stat
;
134 int unixfd
= FILE_GetUnixHandle(hFile
);
138 rc
= fstat(unixfd
,&file_stat
);
140 SetLastError(ErrnoToLastError(errno
));
144 /* Translate the file attributes.
146 lpfi
->dwFileAttributes
= 0;
147 if(file_stat
.st_mode
& S_IFREG
)
148 lpfi
->dwFileAttributes
|= FILE_ATTRIBUTE_NORMAL
;
149 if(file_stat
.st_mode
& S_IFDIR
)
150 lpfi
->dwFileAttributes
|= FILE_ATTRIBUTE_DIRECTORY
;
151 if((file_stat
.st_mode
& S_IWRITE
) == 0)
152 lpfi
->dwFileAttributes
|= FILE_ATTRIBUTE_READONLY
;
154 /* Translate the file times. Use the last modification time
155 * for both the creation time and write time.
157 DOSFS_UnixTimeToFileTime(file_stat
.st_mtime
, &(lpfi
->ftCreationTime
));
158 DOSFS_UnixTimeToFileTime(file_stat
.st_mtime
, &(lpfi
->ftLastWriteTime
));
159 DOSFS_UnixTimeToFileTime(file_stat
.st_atime
, &(lpfi
->ftLastAccessTime
));
161 lpfi
->nFileSizeLow
= file_stat
.st_size
;
162 lpfi
->nNumberOfLinks
= file_stat
.st_nlink
;
163 lpfi
->nFileIndexLow
= file_stat
.st_ino
;
165 /* Zero out currently unused fields.
167 lpfi
->dwVolumeSerialNumber
= 0;
168 lpfi
->nFileSizeHigh
= 0;
169 lpfi
->nFileIndexHigh
= 0;
174 /***********************************************************************
175 * GetFileSize (KERNEL32.220)
177 DWORD
GetFileSize(HFILE hf
,LPDWORD filesizehigh
) {
178 BY_HANDLE_FILE_INFORMATION fi
;
179 DWORD res
= GetFileInformationByHandle(hf
,&fi
);
182 return 0; /* FIXME: correct ? */
184 *filesizehigh
= fi
.nFileSizeHigh
;
185 return fi
.nFileSizeLow
;
188 /***********************************************************************
189 * GetStdHandle (KERNEL32.276)
190 * FIXME: We should probably allocate filehandles for stdin/stdout/stderr
191 * at task creation (with HFILE-handle 0,1,2 respectively) and
192 * return them here. Or at least look, if we created them already.
194 HFILE
GetStdHandle(DWORD nStdHandle
)
201 case STD_INPUT_HANDLE
:
205 case STD_OUTPUT_HANDLE
:
209 case STD_ERROR_HANDLE
:
213 SetLastError(ERROR_INVALID_HANDLE
);
216 hfile
= FILE_DupUnixHandle(unixfd
);
217 if (hfile
== HFILE_ERROR
)
219 FILE_SetFileType( hfile
, FILE_TYPE_CHAR
);
224 /***********************************************************************
225 * SetFilePointer (KERNEL32.492)
227 * Luckily enough, this function maps almost directly into an lseek
228 * call, the exception being the use of 64-bit offsets.
230 DWORD
SetFilePointer(HFILE hFile
, LONG distance
, LONG
*highword
,
238 dprintf_file(stddeb
, "SetFilePointer: 64-bit offsets not yet supported.\n");
243 rc
= _llseek(hFile
, distance
, method
);
245 SetLastError(ErrnoToLastError(errno
));
249 /***********************************************************************
250 * WriteFile (KERNEL32.578)
252 BOOL32
WriteFile(HFILE hFile
, LPVOID lpBuffer
, DWORD numberOfBytesToWrite
,
253 LPDWORD numberOfBytesWritten
, LPOVERLAPPED lpOverlapped
)
257 res
= _lwrite32(hFile
,lpBuffer
,numberOfBytesToWrite
);
259 SetLastError(ErrnoToLastError(errno
));
262 if(numberOfBytesWritten
)
263 *numberOfBytesWritten
= res
;
267 /***********************************************************************
268 * ReadFile (KERNEL32.428)
270 BOOL32
ReadFile(HFILE hFile
, LPVOID lpBuffer
, DWORD numtoread
,
271 LPDWORD numread
, LPOVERLAPPED lpOverlapped
)
275 actual_read
= _lread32(hFile
,lpBuffer
,numtoread
);
276 if(actual_read
== -1) {
277 SetLastError(ErrnoToLastError(errno
));
281 *numread
= actual_read
;
287 /*************************************************************************
288 * CreateFile32A (KERNEL32.45)
290 * Doesn't support character devices, pipes, template files, or a
291 * lot of the 'attributes' flags yet.
293 HFILE
CreateFile32A(LPCSTR filename
, DWORD access
, DWORD sharing
,
294 LPSECURITY_ATTRIBUTES security
, DWORD creation
,
295 DWORD attributes
, HANDLE32
template)
297 int access_flags
, create_flags
;
299 /* Translate the various flags to Unix-style.
301 access_flags
= TranslateAccessFlags(access
);
302 create_flags
= TranslateCreationFlags(creation
);
305 dprintf_file(stddeb
, "CreateFile: template handles not supported.\n");
307 /* If the name starts with '\\?' or '\\.', ignore the first 3 chars.
309 if(!strncmp(filename
, "\\\\?", 3) || !strncmp(filename
, "\\\\.", 3))
312 /* If the name still starts with '\\', it's a UNC name.
314 if(!strncmp(filename
, "\\\\", 2))
316 dprintf_file(stddeb
, "CreateFile: UNC names not supported.\n");
317 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
321 /* If the name is either CONIN$ or CONOUT$, give them stdin
322 * or stdout, respectively.
324 if(!strcmp(filename
, "CONIN$")) return GetStdHandle( STD_INPUT_HANDLE
);
325 if(!strcmp(filename
, "CONOUT$")) return GetStdHandle( STD_OUTPUT_HANDLE
);
327 return FILE_Open( filename
, access_flags
| create_flags
);
331 /*************************************************************************
332 * CreateFile32W (KERNEL32.48)
334 HFILE
CreateFile32W(LPCWSTR filename
, DWORD access
, DWORD sharing
,
335 LPSECURITY_ATTRIBUTES security
, DWORD creation
,
336 DWORD attributes
, HANDLE32
template)
338 LPSTR afn
= HEAP_strdupWtoA( GetProcessHeap(), 0, filename
);
339 HFILE res
= CreateFile32A( afn
, access
, sharing
, security
, creation
,
340 attributes
, template );
341 HeapFree( GetProcessHeap(), 0, afn
);
345 /*************************************************************************
346 * SetHandleCount32 (KERNEL32.494)
348 UINT32
SetHandleCount32( UINT32 cHandles
)
350 return SetHandleCount16(cHandles
);
354 int CloseFileHandle(HFILE hFile
)
361 static int TranslateAccessFlags(DWORD access_flags
)
375 case (GENERIC_READ
| GENERIC_WRITE
):
383 static int TranslateCreationFlags(DWORD create_flags
)
390 rc
= O_CREAT
| O_EXCL
;
394 rc
= O_CREAT
| O_TRUNC
;
405 case TRUNCATE_EXISTING
:
414 /**************************************************************************
415 * GetFileAttributes32A (KERNEL32.217)
417 DWORD
GetFileAttributes32A(LPCSTR lpFileName
)
423 dprintf_file(stddeb
,"GetFileAttributesA(%s)\n",lpFileName
);
424 fn
=(LPSTR
)DOSFS_GetUnixFileName(lpFileName
,FALSE
);
425 /* fn points to a static buffer, don't free it */
426 if(stat(fn
,&buf
)==-1) {
427 SetLastError(ErrnoToLastError(errno
));
430 if(buf
.st_mode
& S_IFREG
)
431 res
|= FILE_ATTRIBUTE_NORMAL
;
432 if(buf
.st_mode
& S_IFDIR
)
433 res
|= FILE_ATTRIBUTE_DIRECTORY
;
434 if((buf
.st_mode
& S_IWRITE
) == 0)
435 res
|= FILE_ATTRIBUTE_READONLY
;
439 /**************************************************************************
440 * GetFileAttributes32W (KERNEL32.218)
442 DWORD
GetFileAttributes32W(LPCWSTR lpFileName
)
444 LPSTR afn
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName
);
445 DWORD res
= GetFileAttributes32A( afn
);
446 HeapFree( GetProcessHeap(), 0, afn
);
451 /**************************************************************************
452 * SetFileAttributes32A (KERNEL32.490)
454 BOOL32
SetFileAttributes32A(LPCSTR lpFileName
, DWORD attributes
)
457 LPSTR fn
=(LPSTR
)DOSFS_GetUnixFileName(lpFileName
,FALSE
);
459 dprintf_file(stddeb
,"SetFileAttributes(%s,%lx)\n",lpFileName
,attributes
);
460 if(stat(fn
,&buf
)==-1) {
461 SetLastError(ErrnoToLastError(errno
));
464 if (attributes
& FILE_ATTRIBUTE_READONLY
) {
465 buf
.st_mode
&= ~0222; /* octal!, clear write permission bits */
466 attributes
&= ~FILE_ATTRIBUTE_READONLY
;
468 attributes
&= ~(FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
);
470 fprintf(stdnimp
,"SetFileAttributesA(%s):%lx attribute(s) not implemented.\n",lpFileName
,attributes
);
471 if (-1==chmod(fn
,buf
.st_mode
)) {
472 SetLastError(ErrnoToLastError(errno
));
478 /**************************************************************************
479 * SetFileAttributes32W (KERNEL32.491)
481 BOOL32
SetFileAttributes32W(LPCWSTR lpFileName
, DWORD attributes
)
483 LPSTR afn
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName
);
484 BOOL32 res
= SetFileAttributes32A( afn
, attributes
);
485 HeapFree( GetProcessHeap(), 0, afn
);
489 /**************************************************************************
490 * SetEndOfFile (KERNEL32.483)
492 BOOL32
SetEndOfFile(HFILE hFile
)
494 int unixfd
= FILE_GetUnixHandle(hFile
);
496 dprintf_file(stddeb
,"SetEndOfFile(%lx)\n",(LONG
)hFile
);
499 if (-1==ftruncate(unixfd
,lseek(unixfd
,0,SEEK_CUR
))) {
500 SetLastError(ErrnoToLastError(errno
));
507 /**************************************************************************
508 * MoveFileA (KERNEL32.387)
510 BOOL32
MoveFile32A(LPCSTR fn1
,LPCSTR fn2
)
515 dprintf_file(stddeb
,"MoveFileA(%s,%s)\n",fn1
,fn2
);
516 ufn1
= (LPSTR
)DOSFS_GetUnixFileName(fn1
,FALSE
);
518 SetLastError(ErrnoToLastError(ENOENT
));
521 ufn1
= xstrdup(ufn1
);
522 ufn2
= (LPSTR
)DOSFS_GetUnixFileName(fn2
,FALSE
);
524 SetLastError(ErrnoToLastError(ENOENT
));
527 ufn2
= xstrdup(ufn2
);
528 if (-1==rename(ufn1
,ufn2
)) {
529 SetLastError(ErrnoToLastError(errno
));
539 /**************************************************************************
540 * MoveFileW (KERNEL32.390)
542 BOOL32
MoveFile32W(LPCWSTR fn1
,LPCWSTR fn2
)
544 LPSTR afn1
= HEAP_strdupWtoA( GetProcessHeap(), 0, fn1
);
545 LPSTR afn2
= HEAP_strdupWtoA( GetProcessHeap(), 0, fn2
);
546 BOOL32 res
= MoveFile32A( afn1
, afn2
);
547 HeapFree( GetProcessHeap(), 0, afn1
);
548 HeapFree( GetProcessHeap(), 0, afn2
);
552 VOID
SetFileApisToOEM()
554 fprintf(stdnimp
,"SetFileApisToOEM(),stub!\n");
557 VOID
SetFileApisToANSI()
559 fprintf(stdnimp
,"SetFileApisToANSI(),stub!\n");
562 BOOL32
AreFileApisANSI()
564 fprintf(stdnimp
,"AreFileApisANSI(),stub!\n");
569 BOOL32
CopyFile32A(LPCSTR sourcefn
,LPCSTR destfn
,BOOL32 failifexists
)
576 fprintf(stddeb
,"CopyFile: %s -> %s\n",sourcefn
,destfn
);
577 hf1
= OpenFile(sourcefn
,&of
,OF_READ
);
578 if (hf1
==HFILE_ERROR
)
581 hf2
= OpenFile(sourcefn
,&of
,OF_WRITE
);
582 if (hf2
!= HFILE_ERROR
)
586 hf2
= OpenFile(sourcefn
,&of
,OF_WRITE
);
587 if (hf2
== HFILE_ERROR
)
590 while ((lastread
=_lread16(hf1
,buffer
,sizeof(buffer
)))>0) {
592 while (curlen
<lastread
) {
593 int res
= _lwrite16(hf2
,buffer
+curlen
,lastread
-curlen
);
605 HFILE hFile
,DWORD dwFileOffsetLow
,DWORD dwFileOffsetHigh
,
606 DWORD nNumberOfBytesToLockLow
,DWORD nNumberOfBytesToLockHigh
)
608 fprintf(stdnimp
,"LockFile(%d,0x%08lx%08lx,0x%08lx%08lx),stub!\n",
609 hFile
,dwFileOffsetHigh
,dwFileOffsetLow
,
610 nNumberOfBytesToLockHigh
,nNumberOfBytesToLockLow
617 HFILE hFile
,DWORD dwFileOffsetLow
,DWORD dwFileOffsetHigh
,
618 DWORD nNumberOfBytesToUnlockLow
,DWORD nNumberOfBytesToUnlockHigh
)
620 fprintf(stdnimp
,"UnlockFile(%d,0x%08lx%08lx,0x%08lx%08lx),stub!\n",
621 hFile
,dwFileOffsetHigh
,dwFileOffsetLow
,
622 nNumberOfBytesToUnlockHigh
,nNumberOfBytesToUnlockLow