2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/file/file.c
5 * PURPOSE: Directory functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * GetTempFileName is modified from WINE [ Alexandre Juiliard ]
12 /* FIXME: the large integer manipulations in this file dont handle overflow */
14 /* INCLUDES ****************************************************************/
17 #include <ddk/ntddk.h>
22 #include <kernel32/kernel32.h>
24 #define LPPROGRESS_ROUTINE void*
26 /* GLOBALS ******************************************************************/
28 static BOOLEAN bIsFileApiAnsi
; // set the file api to ansi or oem
30 /* FUNCTIONS ****************************************************************/
32 VOID STDCALL
SetFileApisToOEM(VOID
)
34 bIsFileApiAnsi
= FALSE
;
37 WINBASEAPI VOID WINAPI
SetFileApisToANSI(VOID
)
39 bIsFileApiAnsi
= TRUE
;
42 WINBOOL STDCALL
AreFileApisANSI(VOID
)
44 return(bIsFileApiAnsi
);
47 HFILE STDCALL
OpenFile(LPCSTR lpFileName
,
48 LPOFSTRUCT lpReOpenBuff
,
52 HANDLE FileHandle
= NULL
;
53 UNICODE_STRING FileNameString
;
54 WCHAR FileNameW
[MAX_PATH
];
55 WCHAR PathNameW
[MAX_PATH
];
57 OBJECT_ATTRIBUTES ObjectAttributes
;
58 IO_STATUS_BLOCK IoStatusBlock
;
62 if (lpReOpenBuff
== NULL
)
68 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
70 FileNameW
[i
] = *lpFileName
;
76 Len
= SearchPathW(NULL
,FileNameW
,NULL
,MAX_PATH
,PathNameW
,&FilePart
);
83 FileNameString
.Length
= lstrlenW(PathNameW
)*sizeof(WCHAR
);
84 FileNameString
.Buffer
= PathNameW
;
85 FileNameString
.MaximumLength
= FileNameString
.Length
+sizeof(WCHAR
);
87 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
88 ObjectAttributes
.RootDirectory
= NULL
;
89 ObjectAttributes
.ObjectName
= &FileNameString
;
90 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
91 ObjectAttributes
.SecurityDescriptor
= NULL
;
92 ObjectAttributes
.SecurityQualityOfService
= NULL
;
95 // FILE_NO_INTERMEDIATE_BUFFERING
97 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
100 errCode
= NtOpenFile(&FileHandle
,
101 GENERIC_READ
|SYNCHRONIZE
,
105 FILE_NON_DIRECTORY_FILE
);
107 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
109 if (!NT_SUCCESS(errCode
))
111 SetLastError(RtlNtStatusToDosError(errCode
));
112 return (HFILE
)INVALID_HANDLE_VALUE
;
115 return (HFILE
)FileHandle
;
118 WINBOOL STDCALL
FlushFileBuffers(HANDLE hFile
)
121 IO_STATUS_BLOCK IoStatusBlock
;
123 errCode
= NtFlushBuffersFile(hFile
,
125 if (!NT_SUCCESS(errCode
))
127 SetLastError(RtlNtStatusToDosError(errCode
));
134 DWORD STDCALL
SetFilePointer(HANDLE hFile
,
135 LONG lDistanceToMove
,
136 PLONG lpDistanceToMoveHigh
,
139 FILE_POSITION_INFORMATION FilePosition
;
140 FILE_END_OF_FILE_INFORMATION FileEndOfFile
;
142 IO_STATUS_BLOCK IoStatusBlock
;
144 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
145 hFile
,lDistanceToMove
,dwMoveMethod
);
147 if (dwMoveMethod
== FILE_CURRENT
)
149 NtQueryInformationFile(hFile
,
152 sizeof(FILE_POSITION_INFORMATION
),
153 FilePositionInformation
);
154 FilePosition
.CurrentByteOffset
.LowPart
+= lDistanceToMove
;
155 if (lpDistanceToMoveHigh
!= NULL
)
157 FilePosition
.CurrentByteOffset
.HighPart
=
158 FilePosition
.CurrentByteOffset
.HighPart
+
159 *lpDistanceToMoveHigh
;
162 else if (dwMoveMethod
== FILE_END
)
164 NtQueryInformationFile(hFile
,&IoStatusBlock
,&FileEndOfFile
, sizeof(FILE_END_OF_FILE_INFORMATION
),FileEndOfFileInformation
);
165 FilePosition
.CurrentByteOffset
.LowPart
=
166 FileEndOfFile
.EndOfFile
.LowPart
- lDistanceToMove
;
167 if ( lpDistanceToMoveHigh
!= NULL
)
169 FilePosition
.CurrentByteOffset
.HighPart
=
170 FileEndOfFile
.EndOfFile
.HighPart
- *lpDistanceToMoveHigh
;
174 FilePosition
.CurrentByteOffset
.HighPart
=
175 FileEndOfFile
.EndOfFile
.HighPart
;
178 else if ( dwMoveMethod
== FILE_BEGIN
)
180 FilePosition
.CurrentByteOffset
.LowPart
= lDistanceToMove
;
181 if ( lpDistanceToMoveHigh
!= NULL
)
183 FilePosition
.CurrentByteOffset
.HighPart
=
184 *lpDistanceToMoveHigh
;
188 FilePosition
.CurrentByteOffset
.HighPart
= 0;
192 errCode
= NtSetInformationFile(hFile
,
195 sizeof(FILE_POSITION_INFORMATION
),
196 FilePositionInformation
);
197 if (!NT_SUCCESS(errCode
))
199 SetLastError(RtlNtStatusToDosError(errCode
));
203 if (lpDistanceToMoveHigh
!= NULL
)
205 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.HighPart
;
207 return FilePosition
.CurrentByteOffset
.LowPart
;
210 DWORD STDCALL
GetFileType(HANDLE hFile
)
212 return FILE_TYPE_UNKNOWN
;
216 DWORD STDCALL
GetFileSize(HANDLE hFile
,
217 LPDWORD lpFileSizeHigh
)
220 FILE_STANDARD_INFORMATION FileStandard
;
221 IO_STATUS_BLOCK IoStatusBlock
;
224 errCode
= NtQueryInformationFile(hFile
,
227 sizeof(FILE_STANDARD_INFORMATION
),
228 FileStandardInformation
);
229 if (!NT_SUCCESS(errCode
))
232 SetLastError(RtlNtStatusToDosError(errCode
));
233 if ( lpFileSizeHigh
== NULL
)
242 if ( lpFileSizeHigh
!= NULL
)
243 *lpFileSizeHigh
= FileStandard
.AllocationSize
.HighPart
;
246 return FileStandard
.AllocationSize
.LowPart
;
249 DWORD STDCALL
GetCompressedFileSizeA(LPCSTR lpFileName
,
250 LPDWORD lpFileSizeHigh
)
252 WCHAR FileNameW
[MAX_PATH
];
256 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
258 FileNameW
[i
] = *lpFileName
;
264 return GetCompressedFileSizeW(FileNameW
,lpFileSizeHigh
);
267 DWORD STDCALL
GetCompressedFileSizeW(LPCWSTR lpFileName
,
268 LPDWORD lpFileSizeHigh
)
270 FILE_COMPRESSION_INFORMATION FileCompression
;
272 IO_STATUS_BLOCK IoStatusBlock
;
275 hFile
= CreateFileW(lpFileName
,
280 FILE_ATTRIBUTE_NORMAL
,
283 errCode
= NtQueryInformationFile(hFile
,
286 sizeof(FILE_COMPRESSION_INFORMATION
),
287 FileCompressionInformation
);
288 if (!NT_SUCCESS(errCode
))
291 SetLastError(RtlNtStatusToDosError(errCode
));
300 WINBOOL STDCALL
GetFileInformationByHandle(HANDLE hFile
,
301 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
303 FILE_DIRECTORY_INFORMATION FileDirectory
;
304 FILE_INTERNAL_INFORMATION FileInternal
;
305 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
306 FILE_STANDARD_INFORMATION FileStandard
;
308 IO_STATUS_BLOCK IoStatusBlock
;
310 errCode
= NtQueryInformationFile(hFile
,
313 sizeof(FILE_DIRECTORY_INFORMATION
),
314 FileDirectoryInformation
);
315 if (!NT_SUCCESS(errCode
))
317 SetLastError(RtlNtStatusToDosError(errCode
));
320 lpFileInformation
->dwFileAttributes
= (DWORD
)FileDirectory
.FileAttributes
;
321 memcpy(&lpFileInformation
->ftCreationTime
,&FileDirectory
.CreationTime
,sizeof(LARGE_INTEGER
));
322 memcpy(&lpFileInformation
->ftLastAccessTime
,&FileDirectory
.LastAccessTime
,sizeof(LARGE_INTEGER
));
323 memcpy(&lpFileInformation
->ftLastWriteTime
, &FileDirectory
.LastWriteTime
,sizeof(LARGE_INTEGER
));
324 lpFileInformation
->nFileSizeHigh
= FileDirectory
.AllocationSize
.HighPart
;
325 lpFileInformation
->nFileSizeLow
= FileDirectory
.AllocationSize
.LowPart
;
327 errCode
= NtQueryInformationFile(hFile
,
330 sizeof(FILE_INTERNAL_INFORMATION
),
331 FileInternalInformation
);
332 if (!NT_SUCCESS(errCode
))
334 SetLastError(RtlNtStatusToDosError(errCode
));
337 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.HighPart
;
338 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.LowPart
;
340 errCode
= NtQueryVolumeInformationFile(hFile
,
343 sizeof(FILE_FS_VOLUME_INFORMATION
),
344 FileFsVolumeInformation
);
345 if (!NT_SUCCESS(errCode
))
347 SetLastError(RtlNtStatusToDosError(errCode
));
350 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.VolumeSerialNumber
;
352 errCode
= NtQueryInformationFile(hFile
,
355 sizeof(FILE_STANDARD_INFORMATION
),
356 FileStandardInformation
);
357 if (!NT_SUCCESS(errCode
))
360 SetLastError(RtlNtStatusToDosError(errCode
));
363 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
373 DWORD STDCALL
GetFileAttributesA(LPCSTR lpFileName
)
376 WCHAR FileNameW
[MAX_PATH
];
379 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
381 FileNameW
[i
] = *lpFileName
;
386 return GetFileAttributesW(FileNameW
);
390 DWORD STDCALL
GetFileAttributesW(LPCWSTR lpFileName
)
392 IO_STATUS_BLOCK IoStatusBlock
;
393 FILE_BASIC_INFORMATION FileBasic
;
397 hFile
= CreateFileW(lpFileName
,
398 FILE_READ_ATTRIBUTES
,
402 FILE_ATTRIBUTE_NORMAL
,
406 errCode
= NtQueryInformationFile(hFile
,
409 sizeof(FILE_BASIC_INFORMATION
),
410 FileBasicInformation
);
411 if (!NT_SUCCESS(errCode
))
414 SetLastError(RtlNtStatusToDosError(errCode
));
418 return (DWORD
)FileBasic
.FileAttributes
;
421 WINBOOL STDCALL
SetFileAttributesA(LPCSTR lpFileName
,
422 DWORD dwFileAttributes
)
425 WCHAR FileNameW
[MAX_PATH
];
427 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
429 FileNameW
[i
] = *lpFileName
;
434 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
438 WINBOOL STDCALL
SetFileAttributesW(LPCWSTR lpFileName
,
439 DWORD dwFileAttributes
)
441 IO_STATUS_BLOCK IoStatusBlock
;
442 FILE_BASIC_INFORMATION FileBasic
;
446 hFile
= CreateFileW(lpFileName
,
447 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
451 FILE_ATTRIBUTE_NORMAL
,
454 errCode
= NtQueryInformationFile(hFile
,
457 sizeof(FILE_BASIC_INFORMATION
),
458 FileBasicInformation
);
459 if (!NT_SUCCESS(errCode
))
462 SetLastError(RtlNtStatusToDosError(errCode
));
465 FileBasic
.FileAttributes
= dwFileAttributes
;
466 errCode
= NtSetInformationFile(hFile
,
469 sizeof(FILE_BASIC_INFORMATION
),
470 FileBasicInformation
);
471 if (!NT_SUCCESS(errCode
))
474 SetLastError(RtlNtStatusToDosError(errCode
));
485 UINT STDCALL
GetTempFileNameA(LPCSTR lpPathName
,
486 LPCSTR lpPrefixString
,
488 LPSTR lpTempFileName
)
491 UINT unique
= uUnique
;
493 if (lpPathName
== NULL
)
497 uUnique
= GetCurrentTime();
499 * sprintf(lpTempFileName,"%s\\%c%.3s%4.4x%s",
500 * lpPathName,'~',lpPrefixString,uUnique,".tmp");
505 while ((hFile
= CreateFileA(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
506 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
507 0)) == INVALID_HANDLE_VALUE
)
509 // wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
510 // lpPathName,'~',lpPrefixString,++uUnique,".tmp");
513 CloseHandle((HANDLE
)hFile
);
518 UINT STDCALL
GetTempFileNameW(LPCWSTR lpPathName
,
519 LPCWSTR lpPrefixString
,
521 LPWSTR lpTempFileName
)
524 UINT unique
= uUnique
;
526 if (lpPathName
== NULL
)
530 uUnique
= GetCurrentTime();
532 // swprintf(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
533 // lpPathName,'~',lpPrefixString,uUnique,L".tmp");
538 while ((hFile
= CreateFileW(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
539 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
540 0)) == INVALID_HANDLE_VALUE
)
542 // wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
543 // lpPathName,'~',lpPrefixString,++uUnique,L".tmp");
546 CloseHandle((HANDLE
)hFile
);
550 WINBOOL STDCALL
GetFileTime(HANDLE hFile
,
551 LPFILETIME lpCreationTime
,
552 LPFILETIME lpLastAccessTime
,
553 LPFILETIME lpLastWriteTime
)
555 IO_STATUS_BLOCK IoStatusBlock
;
556 FILE_BASIC_INFORMATION FileBasic
;
559 errCode
= NtQueryInformationFile(hFile
,
562 sizeof(FILE_BASIC_INFORMATION
),
563 FileBasicInformation
);
564 if (!NT_SUCCESS(errCode
))
566 SetLastError(RtlNtStatusToDosError(errCode
));
569 memcpy(lpCreationTime
,&FileBasic
.CreationTime
,sizeof(FILETIME
));
570 memcpy(lpLastAccessTime
,&FileBasic
.LastAccessTime
,sizeof(FILETIME
));
571 memcpy(lpLastWriteTime
,&FileBasic
.LastWriteTime
,sizeof(FILETIME
));
575 WINBOOL STDCALL
SetFileTime(HANDLE hFile
,
576 CONST FILETIME
*lpCreationTime
,
577 CONST FILETIME
*lpLastAccessTime
,
578 CONST FILETIME
*lpLastWriteTime
)
580 FILE_BASIC_INFORMATION FileBasic
;
581 IO_STATUS_BLOCK IoStatusBlock
;
584 memcpy(&FileBasic
.CreationTime
,lpCreationTime
,sizeof(FILETIME
));
585 memcpy(&FileBasic
.LastAccessTime
,lpLastAccessTime
,sizeof(FILETIME
));
586 memcpy(&FileBasic
.LastWriteTime
,lpLastWriteTime
,sizeof(FILETIME
));
588 // shoud i initialize changetime ???
590 errCode
= NtSetInformationFile(hFile
,
593 sizeof(FILE_BASIC_INFORMATION
),
594 FileBasicInformation
);
595 if (!NT_SUCCESS(errCode
))
597 SetLastError(RtlNtStatusToDosError(errCode
));
604 WINBOOL STDCALL
SetEndOfFile(HANDLE hFile
)
608 return WriteFile(hFile
,&x
,1,&Num
,NULL
);