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 SET_LARGE_INTEGER_LOW_PART(FilePosition
.CurrentByteOffset
,
155 GET_LARGE_INTEGER_LOW_PART(FilePosition
.CurrentByteOffset
) +
157 if (lpDistanceToMoveHigh
!= NULL
)
159 SET_LARGE_INTEGER_HIGH_PART(FilePosition
.CurrentByteOffset
,
160 GET_LARGE_INTEGER_HIGH_PART(FilePosition
.CurrentByteOffset
) +
161 *lpDistanceToMoveHigh
);
164 else if (dwMoveMethod
== FILE_END
)
166 NtQueryInformationFile(hFile
,&IoStatusBlock
,&FileEndOfFile
, sizeof(FILE_END_OF_FILE_INFORMATION
),FileEndOfFileInformation
);
167 SET_LARGE_INTEGER_LOW_PART(FilePosition
.CurrentByteOffset
,
168 GET_LARGE_INTEGER_LOW_PART(FileEndOfFile
.EndOfFile
) -
170 if ( lpDistanceToMoveHigh
!= NULL
)
172 SET_LARGE_INTEGER_HIGH_PART(FilePosition
.CurrentByteOffset
,
173 GET_LARGE_INTEGER_HIGH_PART(FileEndOfFile
.EndOfFile
) -
174 *lpDistanceToMoveHigh
);
178 SET_LARGE_INTEGER_HIGH_PART(FilePosition
.CurrentByteOffset
,
179 GET_LARGE_INTEGER_HIGH_PART(FileEndOfFile
.EndOfFile
));
182 else if ( dwMoveMethod
== FILE_BEGIN
)
184 SET_LARGE_INTEGER_LOW_PART(FilePosition
.CurrentByteOffset
,
186 if ( lpDistanceToMoveHigh
!= NULL
)
188 SET_LARGE_INTEGER_HIGH_PART(FilePosition
.CurrentByteOffset
,
189 *lpDistanceToMoveHigh
);
193 SET_LARGE_INTEGER_HIGH_PART(FilePosition
.CurrentByteOffset
,
198 errCode
= NtSetInformationFile(hFile
,
201 sizeof(FILE_POSITION_INFORMATION
),
202 FilePositionInformation
);
203 if (!NT_SUCCESS(errCode
))
205 SetLastError(RtlNtStatusToDosError(errCode
));
209 if (lpDistanceToMoveHigh
!= NULL
)
211 *lpDistanceToMoveHigh
= GET_LARGE_INTEGER_HIGH_PART(
212 FilePosition
.CurrentByteOffset
);
214 return GET_LARGE_INTEGER_LOW_PART(FilePosition
.CurrentByteOffset
);
217 DWORD STDCALL
GetFileType(HANDLE hFile
)
219 return FILE_TYPE_UNKNOWN
;
223 DWORD STDCALL
GetFileSize(HANDLE hFile
,
224 LPDWORD lpFileSizeHigh
)
227 FILE_STANDARD_INFORMATION FileStandard
;
228 IO_STATUS_BLOCK IoStatusBlock
;
231 errCode
= NtQueryInformationFile(hFile
,
234 sizeof(FILE_STANDARD_INFORMATION
),
235 FileStandardInformation
);
236 if (!NT_SUCCESS(errCode
))
239 SetLastError(RtlNtStatusToDosError(errCode
));
240 if ( lpFileSizeHigh
== NULL
)
249 if ( lpFileSizeHigh
!= NULL
)
250 *lpFileSizeHigh
= GET_LARGE_INTEGER_HIGH_PART(FileStandard
.AllocationSize
);
253 return GET_LARGE_INTEGER_LOW_PART(FileStandard
.AllocationSize
);
256 DWORD STDCALL
GetCompressedFileSizeA(LPCSTR lpFileName
,
257 LPDWORD lpFileSizeHigh
)
259 WCHAR FileNameW
[MAX_PATH
];
263 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
265 FileNameW
[i
] = *lpFileName
;
271 return GetCompressedFileSizeW(FileNameW
,lpFileSizeHigh
);
274 DWORD STDCALL
GetCompressedFileSizeW(LPCWSTR lpFileName
,
275 LPDWORD lpFileSizeHigh
)
277 FILE_COMPRESSION_INFORMATION FileCompression
;
279 IO_STATUS_BLOCK IoStatusBlock
;
282 hFile
= CreateFileW(lpFileName
,
287 FILE_ATTRIBUTE_NORMAL
,
290 errCode
= NtQueryInformationFile(hFile
,
293 sizeof(FILE_COMPRESSION_INFORMATION
),
294 FileCompressionInformation
);
295 if (!NT_SUCCESS(errCode
))
298 SetLastError(RtlNtStatusToDosError(errCode
));
307 WINBOOL STDCALL
GetFileInformationByHandle(HANDLE hFile
,
308 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
310 FILE_DIRECTORY_INFORMATION FileDirectory
;
311 FILE_INTERNAL_INFORMATION FileInternal
;
312 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
313 FILE_STANDARD_INFORMATION FileStandard
;
315 IO_STATUS_BLOCK IoStatusBlock
;
317 errCode
= NtQueryInformationFile(hFile
,
320 sizeof(FILE_DIRECTORY_INFORMATION
),
321 FileDirectoryInformation
);
322 if (!NT_SUCCESS(errCode
))
324 SetLastError(RtlNtStatusToDosError(errCode
));
327 lpFileInformation
->dwFileAttributes
= (DWORD
)FileDirectory
.FileAttributes
;
328 memcpy(&lpFileInformation
->ftCreationTime
,&FileDirectory
.CreationTime
,sizeof(LARGE_INTEGER
));
329 memcpy(&lpFileInformation
->ftLastAccessTime
,&FileDirectory
.LastAccessTime
,sizeof(LARGE_INTEGER
));
330 memcpy(&lpFileInformation
->ftLastWriteTime
, &FileDirectory
.LastWriteTime
,sizeof(LARGE_INTEGER
));
331 lpFileInformation
->nFileSizeHigh
= GET_LARGE_INTEGER_HIGH_PART(FileDirectory
.AllocationSize
);
332 lpFileInformation
->nFileSizeLow
= GET_LARGE_INTEGER_LOW_PART(FileDirectory
.AllocationSize
);
334 errCode
= NtQueryInformationFile(hFile
,
337 sizeof(FILE_INTERNAL_INFORMATION
),
338 FileInternalInformation
);
339 if (!NT_SUCCESS(errCode
))
341 SetLastError(RtlNtStatusToDosError(errCode
));
344 lpFileInformation
->nFileIndexHigh
= GET_LARGE_INTEGER_HIGH_PART(FileInternal
.IndexNumber
);
345 lpFileInformation
->nFileIndexLow
= GET_LARGE_INTEGER_LOW_PART(FileInternal
.IndexNumber
);
347 errCode
= NtQueryVolumeInformationFile(hFile
,
350 sizeof(FILE_FS_VOLUME_INFORMATION
),
351 FileFsVolumeInformation
);
352 if (!NT_SUCCESS(errCode
))
354 SetLastError(RtlNtStatusToDosError(errCode
));
357 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.VolumeSerialNumber
;
359 errCode
= NtQueryInformationFile(hFile
,
362 sizeof(FILE_STANDARD_INFORMATION
),
363 FileStandardInformation
);
364 if (!NT_SUCCESS(errCode
))
367 SetLastError(RtlNtStatusToDosError(errCode
));
370 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
380 DWORD STDCALL
GetFileAttributesA(LPCSTR lpFileName
)
383 WCHAR FileNameW
[MAX_PATH
];
386 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
388 FileNameW
[i
] = *lpFileName
;
393 return GetFileAttributesW(FileNameW
);
397 DWORD STDCALL
GetFileAttributesW(LPCWSTR lpFileName
)
399 IO_STATUS_BLOCK IoStatusBlock
;
400 FILE_BASIC_INFORMATION FileBasic
;
404 hFile
= CreateFileW(lpFileName
,
409 FILE_ATTRIBUTE_NORMAL
,
413 errCode
= NtQueryInformationFile(hFile
,
416 sizeof(FILE_BASIC_INFORMATION
),
417 FileBasicInformation
);
418 if (!NT_SUCCESS(errCode
))
421 SetLastError(RtlNtStatusToDosError(errCode
));
425 return (DWORD
)FileBasic
.FileAttributes
;
428 WINBOOL STDCALL
SetFileAttributesA(LPCSTR lpFileName
,
429 DWORD dwFileAttributes
)
432 WCHAR FileNameW
[MAX_PATH
];
434 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
436 FileNameW
[i
] = *lpFileName
;
441 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
445 WINBOOL STDCALL
SetFileAttributesW(LPCWSTR lpFileName
,
446 DWORD dwFileAttributes
)
448 IO_STATUS_BLOCK IoStatusBlock
;
449 FILE_BASIC_INFORMATION FileBasic
;
453 hFile
= CreateFileW(lpFileName
,
454 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
458 FILE_ATTRIBUTE_NORMAL
,
461 errCode
= NtQueryInformationFile(hFile
,
464 sizeof(FILE_BASIC_INFORMATION
),
465 FileBasicInformation
);
466 if (!NT_SUCCESS(errCode
))
469 SetLastError(RtlNtStatusToDosError(errCode
));
472 FileBasic
.FileAttributes
= dwFileAttributes
;
473 errCode
= NtSetInformationFile(hFile
,
476 sizeof(FILE_BASIC_INFORMATION
),
477 FileBasicInformation
);
478 if (!NT_SUCCESS(errCode
))
481 SetLastError(RtlNtStatusToDosError(errCode
));
492 UINT STDCALL
GetTempFileNameA(LPCSTR lpPathName
,
493 LPCSTR lpPrefixString
,
495 LPSTR lpTempFileName
)
498 UINT unique
= uUnique
;
500 if (lpPathName
== NULL
)
504 uUnique
= GetCurrentTime();
506 * sprintf(lpTempFileName,"%s\\%c%.3s%4.4x%s",
507 * lpPathName,'~',lpPrefixString,uUnique,".tmp");
512 while ((hFile
= CreateFileA(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
513 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
514 0)) == INVALID_HANDLE_VALUE
)
516 // wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
517 // lpPathName,'~',lpPrefixString,++uUnique,".tmp");
520 CloseHandle((HANDLE
)hFile
);
525 UINT STDCALL
GetTempFileNameW(LPCWSTR lpPathName
,
526 LPCWSTR lpPrefixString
,
528 LPWSTR lpTempFileName
)
531 UINT unique
= uUnique
;
533 if (lpPathName
== NULL
)
537 uUnique
= GetCurrentTime();
539 // swprintf(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
540 // lpPathName,'~',lpPrefixString,uUnique,L".tmp");
545 while ((hFile
= CreateFileW(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
546 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
547 0)) == INVALID_HANDLE_VALUE
)
549 // wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
550 // lpPathName,'~',lpPrefixString,++uUnique,L".tmp");
553 CloseHandle((HANDLE
)hFile
);
557 WINBOOL STDCALL
GetFileTime(HANDLE hFile
,
558 LPFILETIME lpCreationTime
,
559 LPFILETIME lpLastAccessTime
,
560 LPFILETIME lpLastWriteTime
)
562 IO_STATUS_BLOCK IoStatusBlock
;
563 FILE_BASIC_INFORMATION FileBasic
;
566 errCode
= NtQueryInformationFile(hFile
,
569 sizeof(FILE_BASIC_INFORMATION
),
570 FileBasicInformation
);
571 if (!NT_SUCCESS(errCode
))
573 SetLastError(RtlNtStatusToDosError(errCode
));
576 memcpy(lpCreationTime
,&FileBasic
.CreationTime
,sizeof(FILETIME
));
577 memcpy(lpLastAccessTime
,&FileBasic
.LastAccessTime
,sizeof(FILETIME
));
578 memcpy(lpLastWriteTime
,&FileBasic
.LastWriteTime
,sizeof(FILETIME
));
582 WINBOOL STDCALL
SetFileTime(HANDLE hFile
,
583 CONST FILETIME
*lpCreationTime
,
584 CONST FILETIME
*lpLastAccessTime
,
585 CONST FILETIME
*lpLastWriteTime
)
587 FILE_BASIC_INFORMATION FileBasic
;
588 IO_STATUS_BLOCK IoStatusBlock
;
591 memcpy(&FileBasic
.CreationTime
,lpCreationTime
,sizeof(FILETIME
));
592 memcpy(&FileBasic
.LastAccessTime
,lpLastAccessTime
,sizeof(FILETIME
));
593 memcpy(&FileBasic
.LastWriteTime
,lpLastWriteTime
,sizeof(FILETIME
));
595 // shoud i initialize changetime ???
597 errCode
= NtSetInformationFile(hFile
,
600 sizeof(FILE_BASIC_INFORMATION
),
601 FileBasicInformation
);
602 if (!NT_SUCCESS(errCode
))
604 SetLastError(RtlNtStatusToDosError(errCode
));
611 WINBOOL STDCALL
SetEndOfFile(HANDLE hFile
)
615 return WriteFile(hFile
,&x
,1,&Num
,NULL
);