Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfileinfo.c
Go to the documentation of this file.
00001 /* $Id: fileinfo.c 54326 2011-11-07 00:18:13Z ion $ 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS system libraries 00005 * FILE: lib/kernel32/file/file.c 00006 * PURPOSE: Directory functions 00007 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) 00008 * Pierre Schweitzer (pierre.schweitzer@reactos.org) 00009 * UPDATE HISTORY: 00010 * Created 01/11/98 00011 */ 00012 00013 /* INCLUDES *****************************************************************/ 00014 00015 #include <k32.h> 00016 #define NDEBUG 00017 #include <debug.h> 00018 DEBUG_CHANNEL(kernel32file); 00019 00020 /* FUNCTIONS ****************************************************************/ 00021 00022 PWCHAR 00023 FilenameA2W(LPCSTR NameA, BOOL alloc) 00024 { 00025 ANSI_STRING str; 00026 UNICODE_STRING strW; 00027 PUNICODE_STRING pstrW; 00028 NTSTATUS Status; 00029 00030 //ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer); 00031 ASSERT(NtCurrentTeb()->StaticUnicodeString.MaximumLength == sizeof(NtCurrentTeb()->StaticUnicodeBuffer)); 00032 00033 RtlInitAnsiString(&str, NameA); 00034 pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString; 00035 00036 if (bIsFileApiAnsi) 00037 Status= RtlAnsiStringToUnicodeString( pstrW, &str, (BOOLEAN)alloc ); 00038 else 00039 Status= RtlOemStringToUnicodeString( pstrW, &str, (BOOLEAN)alloc ); 00040 00041 if (NT_SUCCESS(Status)) 00042 return pstrW->Buffer; 00043 00044 if (Status== STATUS_BUFFER_OVERFLOW) 00045 SetLastError( ERROR_FILENAME_EXCED_RANGE ); 00046 else 00047 BaseSetLastNTError(Status); 00048 00049 return NULL; 00050 } 00051 00052 00053 /* 00054 No copy/conversion is done if the dest. buffer is too small. 00055 00056 Returns: 00057 Success: number of TCHARS copied into dest. buffer NOT including nullterm 00058 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm 00059 */ 00060 DWORD 00061 FilenameU2A_FitOrFail( 00062 LPSTR DestA, 00063 INT destLen, /* buffer size in TCHARS incl. nullchar */ 00064 PUNICODE_STRING SourceU 00065 ) 00066 { 00067 DWORD ret; 00068 00069 /* destLen should never exceed MAX_PATH */ 00070 if (destLen > MAX_PATH) destLen = MAX_PATH; 00071 00072 ret = bIsFileApiAnsi? RtlUnicodeStringToAnsiSize(SourceU) : RtlUnicodeStringToOemSize(SourceU); 00073 /* ret incl. nullchar */ 00074 00075 if (DestA && (INT)ret <= destLen) 00076 { 00077 ANSI_STRING str; 00078 00079 str.Buffer = DestA; 00080 str.MaximumLength = (USHORT)destLen; 00081 00082 00083 if (bIsFileApiAnsi) 00084 RtlUnicodeStringToAnsiString(&str, SourceU, FALSE ); 00085 else 00086 RtlUnicodeStringToOemString(&str, SourceU, FALSE ); 00087 00088 ret = str.Length; /* SUCCESS: length without terminating 0 */ 00089 } 00090 00091 return ret; 00092 } 00093 00094 00095 /* 00096 No copy/conversion is done if the dest. buffer is too small. 00097 00098 Returns: 00099 Success: number of TCHARS copied into dest. buffer NOT including nullterm 00100 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm 00101 */ 00102 DWORD 00103 FilenameW2A_FitOrFail( 00104 LPSTR DestA, 00105 INT destLen, /* buffer size in TCHARS incl. nullchar */ 00106 LPCWSTR SourceW, 00107 INT sourceLen /* buffer size in TCHARS incl. nullchar */ 00108 ) 00109 { 00110 UNICODE_STRING strW; 00111 00112 if (sourceLen < 0) sourceLen = wcslen(SourceW) + 1; 00113 00114 strW.Buffer = (PWCHAR)SourceW; 00115 strW.MaximumLength = sourceLen * sizeof(WCHAR); 00116 strW.Length = strW.MaximumLength - sizeof(WCHAR); 00117 00118 return FilenameU2A_FitOrFail(DestA, destLen, &strW); 00119 } 00120 00121 00122 /* 00123 Return: num. TCHARS copied into dest including nullterm 00124 */ 00125 DWORD 00126 FilenameA2W_N( 00127 LPWSTR dest, 00128 INT destlen, /* buffer size in TCHARS incl. nullchar */ 00129 LPCSTR src, 00130 INT srclen /* buffer size in TCHARS incl. nullchar */ 00131 ) 00132 { 00133 DWORD ret; 00134 00135 if (srclen < 0) srclen = strlen( src ) + 1; 00136 00137 if (bIsFileApiAnsi) 00138 RtlMultiByteToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen ); 00139 else 00140 RtlOemToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen ); 00141 00142 if (ret) dest[(ret/sizeof(WCHAR))-1]=0; 00143 00144 return ret/sizeof(WCHAR); 00145 } 00146 00147 /* 00148 Return: num. TCHARS copied into dest including nullterm 00149 */ 00150 DWORD 00151 FilenameW2A_N( 00152 LPSTR dest, 00153 INT destlen, /* buffer size in TCHARS incl. nullchar */ 00154 LPCWSTR src, 00155 INT srclen /* buffer size in TCHARS incl. nullchar */ 00156 ) 00157 { 00158 DWORD ret; 00159 00160 if (srclen < 0) srclen = wcslen( src ) + 1; 00161 00162 if (bIsFileApiAnsi) 00163 RtlUnicodeToMultiByteN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR)); 00164 else 00165 RtlUnicodeToOemN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR) ); 00166 00167 if (ret) dest[ret-1]=0; 00168 00169 return ret; 00170 } 00171 00172 /* 00173 * @implemented 00174 */ 00175 BOOL WINAPI 00176 FlushFileBuffers(IN HANDLE hFile) 00177 { 00178 NTSTATUS Status; 00179 IO_STATUS_BLOCK IoStatusBlock; 00180 00181 hFile = TranslateStdHandle(hFile); 00182 00183 if (IsConsoleHandle(hFile)) 00184 { 00185 return FlushConsoleInputBuffer(hFile); 00186 } 00187 00188 Status = NtFlushBuffersFile(hFile, 00189 &IoStatusBlock); 00190 if (!NT_SUCCESS(Status)) 00191 { 00192 BaseSetLastNTError(Status); 00193 return FALSE; 00194 } 00195 return TRUE; 00196 } 00197 00198 00199 /* 00200 * @implemented 00201 */ 00202 DWORD WINAPI 00203 SetFilePointer(HANDLE hFile, 00204 LONG lDistanceToMove, 00205 PLONG lpDistanceToMoveHigh, 00206 DWORD dwMoveMethod) 00207 { 00208 FILE_POSITION_INFORMATION FilePosition; 00209 FILE_STANDARD_INFORMATION FileStandard; 00210 NTSTATUS errCode; 00211 IO_STATUS_BLOCK IoStatusBlock; 00212 LARGE_INTEGER Distance; 00213 00214 TRACE("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n", 00215 hFile,lDistanceToMove,dwMoveMethod); 00216 00217 if(IsConsoleHandle(hFile)) 00218 { 00219 SetLastError(ERROR_INVALID_HANDLE); 00220 return INVALID_SET_FILE_POINTER; 00221 } 00222 00223 if (lpDistanceToMoveHigh) 00224 { 00225 Distance.u.HighPart = *lpDistanceToMoveHigh; 00226 Distance.u.LowPart = lDistanceToMove; 00227 } 00228 else 00229 { 00230 Distance.QuadPart = lDistanceToMove; 00231 } 00232 00233 switch(dwMoveMethod) 00234 { 00235 case FILE_CURRENT: 00236 errCode = NtQueryInformationFile(hFile, 00237 &IoStatusBlock, 00238 &FilePosition, 00239 sizeof(FILE_POSITION_INFORMATION), 00240 FilePositionInformation); 00241 FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart; 00242 if (!NT_SUCCESS(errCode)) 00243 { 00244 if (lpDistanceToMoveHigh != NULL) 00245 *lpDistanceToMoveHigh = -1; 00246 BaseSetLastNTError(errCode); 00247 return INVALID_SET_FILE_POINTER; 00248 } 00249 break; 00250 case FILE_END: 00251 errCode = NtQueryInformationFile(hFile, 00252 &IoStatusBlock, 00253 &FileStandard, 00254 sizeof(FILE_STANDARD_INFORMATION), 00255 FileStandardInformation); 00256 FilePosition.CurrentByteOffset.QuadPart = 00257 FileStandard.EndOfFile.QuadPart + Distance.QuadPart; 00258 if (!NT_SUCCESS(errCode)) 00259 { 00260 if (lpDistanceToMoveHigh != NULL) 00261 *lpDistanceToMoveHigh = -1; 00262 BaseSetLastNTError(errCode); 00263 return INVALID_SET_FILE_POINTER; 00264 } 00265 break; 00266 case FILE_BEGIN: 00267 FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart; 00268 break; 00269 default: 00270 SetLastError(ERROR_INVALID_PARAMETER); 00271 return INVALID_SET_FILE_POINTER; 00272 } 00273 00274 if(FilePosition.CurrentByteOffset.QuadPart < 0) 00275 { 00276 SetLastError(ERROR_NEGATIVE_SEEK); 00277 return INVALID_SET_FILE_POINTER; 00278 } 00279 00280 if (lpDistanceToMoveHigh == NULL && FilePosition.CurrentByteOffset.HighPart != 0) 00281 { 00282 /* If we're moving the pointer outside of the 32 bit boundaries but 00283 the application only passed a 32 bit value we need to bail out! */ 00284 SetLastError(ERROR_INVALID_PARAMETER); 00285 return INVALID_SET_FILE_POINTER; 00286 } 00287 00288 errCode = NtSetInformationFile(hFile, 00289 &IoStatusBlock, 00290 &FilePosition, 00291 sizeof(FILE_POSITION_INFORMATION), 00292 FilePositionInformation); 00293 if (!NT_SUCCESS(errCode)) 00294 { 00295 if (lpDistanceToMoveHigh != NULL) 00296 *lpDistanceToMoveHigh = -1; 00297 00298 BaseSetLastNTError(errCode); 00299 return INVALID_SET_FILE_POINTER; 00300 } 00301 00302 if (lpDistanceToMoveHigh != NULL) 00303 { 00304 *lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart; 00305 } 00306 00307 if (FilePosition.CurrentByteOffset.u.LowPart == MAXDWORD) 00308 { 00309 /* The value of -1 is valid here, especially when the new 00310 file position is greater than 4 GB. Since NtSetInformationFile 00311 succeeded we never set an error code and we explicitly need 00312 to clear a previously set error code in this case, which 00313 an application will check if INVALID_SET_FILE_POINTER is returned! */ 00314 SetLastError(ERROR_SUCCESS); 00315 } 00316 00317 return FilePosition.CurrentByteOffset.u.LowPart; 00318 } 00319 00320 00321 /* 00322 * @implemented 00323 */ 00324 BOOL 00325 WINAPI 00326 SetFilePointerEx(HANDLE hFile, 00327 LARGE_INTEGER liDistanceToMove, 00328 PLARGE_INTEGER lpNewFilePointer, 00329 DWORD dwMoveMethod) 00330 { 00331 FILE_POSITION_INFORMATION FilePosition; 00332 FILE_STANDARD_INFORMATION FileStandard; 00333 NTSTATUS errCode; 00334 IO_STATUS_BLOCK IoStatusBlock; 00335 00336 if(IsConsoleHandle(hFile)) 00337 { 00338 SetLastError(ERROR_INVALID_HANDLE); 00339 return FALSE; 00340 } 00341 00342 switch(dwMoveMethod) 00343 { 00344 case FILE_CURRENT: 00345 NtQueryInformationFile(hFile, 00346 &IoStatusBlock, 00347 &FilePosition, 00348 sizeof(FILE_POSITION_INFORMATION), 00349 FilePositionInformation); 00350 FilePosition.CurrentByteOffset.QuadPart += liDistanceToMove.QuadPart; 00351 break; 00352 case FILE_END: 00353 NtQueryInformationFile(hFile, 00354 &IoStatusBlock, 00355 &FileStandard, 00356 sizeof(FILE_STANDARD_INFORMATION), 00357 FileStandardInformation); 00358 FilePosition.CurrentByteOffset.QuadPart = 00359 FileStandard.EndOfFile.QuadPart + liDistanceToMove.QuadPart; 00360 break; 00361 case FILE_BEGIN: 00362 FilePosition.CurrentByteOffset.QuadPart = liDistanceToMove.QuadPart; 00363 break; 00364 default: 00365 SetLastError(ERROR_INVALID_PARAMETER); 00366 return FALSE; 00367 } 00368 00369 if(FilePosition.CurrentByteOffset.QuadPart < 0) 00370 { 00371 SetLastError(ERROR_NEGATIVE_SEEK); 00372 return FALSE; 00373 } 00374 00375 errCode = NtSetInformationFile(hFile, 00376 &IoStatusBlock, 00377 &FilePosition, 00378 sizeof(FILE_POSITION_INFORMATION), 00379 FilePositionInformation); 00380 if (!NT_SUCCESS(errCode)) 00381 { 00382 BaseSetLastNTError(errCode); 00383 return FALSE; 00384 } 00385 00386 if (lpNewFilePointer) 00387 { 00388 *lpNewFilePointer = FilePosition.CurrentByteOffset; 00389 } 00390 return TRUE; 00391 } 00392 00393 00394 /* 00395 * @implemented 00396 */ 00397 DWORD WINAPI 00398 GetFileType(HANDLE hFile) 00399 { 00400 FILE_FS_DEVICE_INFORMATION DeviceInfo; 00401 IO_STATUS_BLOCK StatusBlock; 00402 NTSTATUS Status; 00403 00404 /* Get real handle */ 00405 hFile = TranslateStdHandle(hFile); 00406 00407 /* Check for console handle */ 00408 if (IsConsoleHandle(hFile)) 00409 { 00410 if (VerifyConsoleIoHandle(hFile)) 00411 return FILE_TYPE_CHAR; 00412 } 00413 00414 Status = NtQueryVolumeInformationFile(hFile, 00415 &StatusBlock, 00416 &DeviceInfo, 00417 sizeof(FILE_FS_DEVICE_INFORMATION), 00418 FileFsDeviceInformation); 00419 if (!NT_SUCCESS(Status)) 00420 { 00421 BaseSetLastNTError(Status); 00422 return FILE_TYPE_UNKNOWN; 00423 } 00424 00425 switch (DeviceInfo.DeviceType) 00426 { 00427 case FILE_DEVICE_CD_ROM: 00428 case FILE_DEVICE_CD_ROM_FILE_SYSTEM: 00429 case FILE_DEVICE_CONTROLLER: 00430 case FILE_DEVICE_DATALINK: 00431 case FILE_DEVICE_DFS: 00432 case FILE_DEVICE_DISK: 00433 case FILE_DEVICE_DISK_FILE_SYSTEM: 00434 case FILE_DEVICE_VIRTUAL_DISK: 00435 return FILE_TYPE_DISK; 00436 00437 case FILE_DEVICE_KEYBOARD: 00438 case FILE_DEVICE_MOUSE: 00439 case FILE_DEVICE_NULL: 00440 case FILE_DEVICE_PARALLEL_PORT: 00441 case FILE_DEVICE_PRINTER: 00442 case FILE_DEVICE_SERIAL_PORT: 00443 case FILE_DEVICE_SCREEN: 00444 case FILE_DEVICE_SOUND: 00445 case FILE_DEVICE_MODEM: 00446 return FILE_TYPE_CHAR; 00447 00448 case FILE_DEVICE_NAMED_PIPE: 00449 return FILE_TYPE_PIPE; 00450 } 00451 00452 return FILE_TYPE_UNKNOWN; 00453 } 00454 00455 00456 /* 00457 * @implemented 00458 */ 00459 DWORD WINAPI 00460 GetFileSize(HANDLE hFile, 00461 LPDWORD lpFileSizeHigh) 00462 { 00463 NTSTATUS errCode; 00464 FILE_STANDARD_INFORMATION FileStandard; 00465 IO_STATUS_BLOCK IoStatusBlock; 00466 00467 errCode = NtQueryInformationFile(hFile, 00468 &IoStatusBlock, 00469 &FileStandard, 00470 sizeof(FILE_STANDARD_INFORMATION), 00471 FileStandardInformation); 00472 if (!NT_SUCCESS(errCode)) 00473 { 00474 BaseSetLastNTError(errCode); 00475 if ( lpFileSizeHigh == NULL ) 00476 { 00477 return -1; 00478 } 00479 else 00480 { 00481 return 0; 00482 } 00483 } 00484 if ( lpFileSizeHigh != NULL ) 00485 *lpFileSizeHigh = FileStandard.EndOfFile.u.HighPart; 00486 00487 return FileStandard.EndOfFile.u.LowPart; 00488 } 00489 00490 00491 /* 00492 * @implemented 00493 */ 00494 BOOL 00495 WINAPI 00496 GetFileSizeEx( 00497 HANDLE hFile, 00498 PLARGE_INTEGER lpFileSize 00499 ) 00500 { 00501 NTSTATUS errCode; 00502 FILE_STANDARD_INFORMATION FileStandard; 00503 IO_STATUS_BLOCK IoStatusBlock; 00504 00505 errCode = NtQueryInformationFile(hFile, 00506 &IoStatusBlock, 00507 &FileStandard, 00508 sizeof(FILE_STANDARD_INFORMATION), 00509 FileStandardInformation); 00510 if (!NT_SUCCESS(errCode)) 00511 { 00512 BaseSetLastNTError(errCode); 00513 return FALSE; 00514 } 00515 if (lpFileSize) 00516 *lpFileSize = FileStandard.EndOfFile; 00517 00518 return TRUE; 00519 } 00520 00521 00522 /* 00523 * @implemented 00524 */ 00525 DWORD WINAPI 00526 GetCompressedFileSizeA(LPCSTR lpFileName, 00527 LPDWORD lpFileSizeHigh) 00528 { 00529 PWCHAR FileNameW; 00530 00531 if (!(FileNameW = FilenameA2W(lpFileName, FALSE))) 00532 return INVALID_FILE_SIZE; 00533 00534 return GetCompressedFileSizeW(FileNameW, lpFileSizeHigh); 00535 } 00536 00537 00538 /* 00539 * @implemented 00540 */ 00541 DWORD WINAPI 00542 GetCompressedFileSizeW(LPCWSTR lpFileName, 00543 LPDWORD lpFileSizeHigh) 00544 { 00545 FILE_COMPRESSION_INFORMATION FileCompression; 00546 NTSTATUS errCode; 00547 IO_STATUS_BLOCK IoStatusBlock; 00548 HANDLE hFile; 00549 00550 hFile = CreateFileW(lpFileName, 00551 GENERIC_READ, 00552 FILE_SHARE_READ, 00553 NULL, 00554 OPEN_EXISTING, 00555 FILE_ATTRIBUTE_NORMAL, 00556 NULL); 00557 00558 if (hFile == INVALID_HANDLE_VALUE) 00559 return INVALID_FILE_SIZE; 00560 00561 errCode = NtQueryInformationFile(hFile, 00562 &IoStatusBlock, 00563 &FileCompression, 00564 sizeof(FILE_COMPRESSION_INFORMATION), 00565 FileCompressionInformation); 00566 00567 CloseHandle(hFile); 00568 00569 if (!NT_SUCCESS(errCode)) 00570 { 00571 BaseSetLastNTError(errCode); 00572 return INVALID_FILE_SIZE; 00573 } 00574 00575 if(lpFileSizeHigh) 00576 *lpFileSizeHigh = FileCompression.CompressedFileSize.u.HighPart; 00577 00578 SetLastError(NO_ERROR); 00579 return FileCompression.CompressedFileSize.u.LowPart; 00580 } 00581 00582 00583 /* 00584 * @implemented 00585 */ 00586 BOOL WINAPI 00587 GetFileInformationByHandle(HANDLE hFile, 00588 LPBY_HANDLE_FILE_INFORMATION lpFileInformation) 00589 { 00590 struct 00591 { 00592 FILE_FS_VOLUME_INFORMATION FileFsVolume; 00593 WCHAR Name[255]; 00594 } 00595 FileFsVolume; 00596 00597 FILE_BASIC_INFORMATION FileBasic; 00598 FILE_INTERNAL_INFORMATION FileInternal; 00599 FILE_STANDARD_INFORMATION FileStandard; 00600 NTSTATUS errCode; 00601 IO_STATUS_BLOCK IoStatusBlock; 00602 00603 if(IsConsoleHandle(hFile)) 00604 { 00605 SetLastError(ERROR_INVALID_HANDLE); 00606 return FALSE; 00607 } 00608 00609 errCode = NtQueryInformationFile(hFile, 00610 &IoStatusBlock, 00611 &FileBasic, 00612 sizeof(FILE_BASIC_INFORMATION), 00613 FileBasicInformation); 00614 if (!NT_SUCCESS(errCode)) 00615 { 00616 BaseSetLastNTError(errCode); 00617 return FALSE; 00618 } 00619 00620 lpFileInformation->dwFileAttributes = (DWORD)FileBasic.FileAttributes; 00621 00622 lpFileInformation->ftCreationTime.dwHighDateTime = FileBasic.CreationTime.u.HighPart; 00623 lpFileInformation->ftCreationTime.dwLowDateTime = FileBasic.CreationTime.u.LowPart; 00624 00625 lpFileInformation->ftLastAccessTime.dwHighDateTime = FileBasic.LastAccessTime.u.HighPart; 00626 lpFileInformation->ftLastAccessTime.dwLowDateTime = FileBasic.LastAccessTime.u.LowPart; 00627 00628 lpFileInformation->ftLastWriteTime.dwHighDateTime = FileBasic.LastWriteTime.u.HighPart; 00629 lpFileInformation->ftLastWriteTime.dwLowDateTime = FileBasic.LastWriteTime.u.LowPart; 00630 00631 errCode = NtQueryInformationFile(hFile, 00632 &IoStatusBlock, 00633 &FileInternal, 00634 sizeof(FILE_INTERNAL_INFORMATION), 00635 FileInternalInformation); 00636 if (!NT_SUCCESS(errCode)) 00637 { 00638 BaseSetLastNTError(errCode); 00639 return FALSE; 00640 } 00641 00642 lpFileInformation->nFileIndexHigh = FileInternal.IndexNumber.u.HighPart; 00643 lpFileInformation->nFileIndexLow = FileInternal.IndexNumber.u.LowPart; 00644 00645 errCode = NtQueryVolumeInformationFile(hFile, 00646 &IoStatusBlock, 00647 &FileFsVolume, 00648 sizeof(FileFsVolume), 00649 FileFsVolumeInformation); 00650 if (!NT_SUCCESS(errCode)) 00651 { 00652 BaseSetLastNTError(errCode); 00653 return FALSE; 00654 } 00655 00656 lpFileInformation->dwVolumeSerialNumber = FileFsVolume.FileFsVolume.VolumeSerialNumber; 00657 00658 errCode = NtQueryInformationFile(hFile, 00659 &IoStatusBlock, 00660 &FileStandard, 00661 sizeof(FILE_STANDARD_INFORMATION), 00662 FileStandardInformation); 00663 if (!NT_SUCCESS(errCode)) 00664 { 00665 BaseSetLastNTError(errCode); 00666 return FALSE; 00667 } 00668 00669 lpFileInformation->nNumberOfLinks = FileStandard.NumberOfLinks; 00670 lpFileInformation->nFileSizeHigh = FileStandard.EndOfFile.u.HighPart; 00671 lpFileInformation->nFileSizeLow = FileStandard.EndOfFile.u.LowPart; 00672 00673 return TRUE; 00674 } 00675 00676 00677 /* 00678 * @implemented 00679 */ 00680 BOOL WINAPI 00681 GetFileAttributesExW(LPCWSTR lpFileName, 00682 GET_FILEEX_INFO_LEVELS fInfoLevelId, 00683 LPVOID lpFileInformation) 00684 { 00685 FILE_NETWORK_OPEN_INFORMATION FileInformation; 00686 OBJECT_ATTRIBUTES ObjectAttributes; 00687 UNICODE_STRING FileName; 00688 NTSTATUS Status; 00689 WIN32_FILE_ATTRIBUTE_DATA* FileAttributeData; 00690 00691 TRACE("GetFileAttributesExW(%S) called\n", lpFileName); 00692 00693 00694 if (fInfoLevelId != GetFileExInfoStandard || lpFileInformation == NULL) 00695 { 00696 SetLastError(ERROR_INVALID_PARAMETER); 00697 return FALSE; 00698 } 00699 00700 /* Validate and translate the filename */ 00701 if (!RtlDosPathNameToNtPathName_U (lpFileName, 00702 &FileName, 00703 NULL, 00704 NULL)) 00705 { 00706 WARN ("Invalid path '%S'\n", lpFileName); 00707 SetLastError (ERROR_BAD_PATHNAME); 00708 return FALSE; 00709 } 00710 00711 /* build the object attributes */ 00712 InitializeObjectAttributes (&ObjectAttributes, 00713 &FileName, 00714 OBJ_CASE_INSENSITIVE, 00715 NULL, 00716 NULL); 00717 00718 /* Get file attributes */ 00719 Status = NtQueryFullAttributesFile(&ObjectAttributes, 00720 &FileInformation); 00721 00722 RtlFreeUnicodeString (&FileName); 00723 if (!NT_SUCCESS (Status)) 00724 { 00725 WARN ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status); 00726 BaseSetLastNTError (Status); 00727 return FALSE; 00728 } 00729 00730 FileAttributeData = (WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation; 00731 FileAttributeData->dwFileAttributes = FileInformation.FileAttributes; 00732 FileAttributeData->ftCreationTime.dwLowDateTime = FileInformation.CreationTime.u.LowPart; 00733 FileAttributeData->ftCreationTime.dwHighDateTime = FileInformation.CreationTime.u.HighPart; 00734 FileAttributeData->ftLastAccessTime.dwLowDateTime = FileInformation.LastAccessTime.u.LowPart; 00735 FileAttributeData->ftLastAccessTime.dwHighDateTime = FileInformation.LastAccessTime.u.HighPart; 00736 FileAttributeData->ftLastWriteTime.dwLowDateTime = FileInformation.LastWriteTime.u.LowPart; 00737 FileAttributeData->ftLastWriteTime.dwHighDateTime = FileInformation.LastWriteTime.u.HighPart; 00738 FileAttributeData->nFileSizeLow = FileInformation.EndOfFile.u.LowPart; 00739 FileAttributeData->nFileSizeHigh = FileInformation.EndOfFile.u.HighPart; 00740 00741 return TRUE; 00742 } 00743 00744 /* 00745 * @implemented 00746 */ 00747 BOOL WINAPI 00748 GetFileAttributesExA(LPCSTR lpFileName, 00749 GET_FILEEX_INFO_LEVELS fInfoLevelId, 00750 LPVOID lpFileInformation) 00751 { 00752 PWCHAR FileNameW; 00753 00754 if (!(FileNameW = FilenameA2W(lpFileName, FALSE))) 00755 return FALSE; 00756 00757 return GetFileAttributesExW(FileNameW, fInfoLevelId, lpFileInformation); 00758 } 00759 00760 00761 /* 00762 * @implemented 00763 */ 00764 DWORD WINAPI 00765 GetFileAttributesA(LPCSTR lpFileName) 00766 { 00767 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData; 00768 PWSTR FileNameW; 00769 BOOL ret; 00770 00771 if (!lpFileName || !(FileNameW = FilenameA2W(lpFileName, FALSE))) 00772 return INVALID_FILE_ATTRIBUTES; 00773 00774 ret = GetFileAttributesExW(FileNameW, GetFileExInfoStandard, &FileAttributeData); 00775 00776 return ret ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES; 00777 } 00778 00779 00780 /* 00781 * @implemented 00782 */ 00783 DWORD WINAPI 00784 GetFileAttributesW(LPCWSTR lpFileName) 00785 { 00786 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData; 00787 BOOL Result; 00788 00789 TRACE ("GetFileAttributeW(%S) called\n", lpFileName); 00790 00791 Result = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &FileAttributeData); 00792 00793 return Result ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES; 00794 } 00795 00796 00797 /* 00798 * @implemented 00799 */ 00800 BOOL WINAPI 00801 GetFileAttributesByHandle(IN HANDLE hFile, 00802 OUT LPDWORD dwFileAttributes, 00803 IN DWORD dwFlags) 00804 { 00805 FILE_BASIC_INFORMATION FileBasic; 00806 IO_STATUS_BLOCK IoStatusBlock; 00807 NTSTATUS Status; 00808 00809 UNREFERENCED_PARAMETER(dwFlags); 00810 00811 if (IsConsoleHandle(hFile)) 00812 { 00813 SetLastError(ERROR_INVALID_HANDLE); 00814 return FALSE; 00815 } 00816 00817 Status = NtQueryInformationFile(hFile, 00818 &IoStatusBlock, 00819 &FileBasic, 00820 sizeof(FileBasic), 00821 FileBasicInformation); 00822 if (NT_SUCCESS(Status)) 00823 { 00824 *dwFileAttributes = FileBasic.FileAttributes; 00825 return TRUE; 00826 } 00827 00828 BaseSetLastNTError(Status); 00829 return FALSE; 00830 } 00831 00832 00833 /* 00834 * @implemented 00835 */ 00836 BOOL WINAPI 00837 SetFileAttributesByHandle(IN HANDLE hFile, 00838 IN DWORD dwFileAttributes, 00839 IN DWORD dwFlags) 00840 { 00841 FILE_BASIC_INFORMATION FileBasic; 00842 IO_STATUS_BLOCK IoStatusBlock; 00843 NTSTATUS Status; 00844 00845 UNREFERENCED_PARAMETER(dwFlags); 00846 00847 if (IsConsoleHandle(hFile)) 00848 { 00849 SetLastError(ERROR_INVALID_HANDLE); 00850 return FALSE; 00851 } 00852 00853 Status = NtQueryInformationFile(hFile, 00854 &IoStatusBlock, 00855 &FileBasic, 00856 sizeof(FileBasic), 00857 FileBasicInformation); 00858 if (NT_SUCCESS(Status)) 00859 { 00860 FileBasic.FileAttributes = dwFileAttributes; 00861 00862 Status = NtSetInformationFile(hFile, 00863 &IoStatusBlock, 00864 &FileBasic, 00865 sizeof(FileBasic), 00866 FileBasicInformation); 00867 } 00868 00869 if (!NT_SUCCESS(Status)) 00870 { 00871 BaseSetLastNTError(Status); 00872 return FALSE; 00873 } 00874 00875 return TRUE; 00876 } 00877 00878 00879 /* 00880 * @implemented 00881 */ 00882 BOOL WINAPI 00883 SetFileAttributesA( 00884 LPCSTR lpFileName, 00885 DWORD dwFileAttributes) 00886 { 00887 PWCHAR FileNameW; 00888 00889 if (!(FileNameW = FilenameA2W(lpFileName, FALSE))) 00890 return FALSE; 00891 00892 return SetFileAttributesW(FileNameW, dwFileAttributes); 00893 } 00894 00895 00896 /* 00897 * @implemented 00898 */ 00899 BOOL WINAPI 00900 SetFileAttributesW(LPCWSTR lpFileName, 00901 DWORD dwFileAttributes) 00902 { 00903 FILE_BASIC_INFORMATION FileInformation; 00904 OBJECT_ATTRIBUTES ObjectAttributes; 00905 IO_STATUS_BLOCK IoStatusBlock; 00906 UNICODE_STRING FileName; 00907 HANDLE FileHandle; 00908 NTSTATUS Status; 00909 00910 TRACE ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName, dwFileAttributes); 00911 00912 /* Validate and translate the filename */ 00913 if (!RtlDosPathNameToNtPathName_U (lpFileName, 00914 &FileName, 00915 NULL, 00916 NULL)) 00917 { 00918 WARN ("Invalid path\n"); 00919 SetLastError (ERROR_BAD_PATHNAME); 00920 return FALSE; 00921 } 00922 TRACE ("FileName: \'%wZ\'\n", &FileName); 00923 00924 /* build the object attributes */ 00925 InitializeObjectAttributes (&ObjectAttributes, 00926 &FileName, 00927 OBJ_CASE_INSENSITIVE, 00928 NULL, 00929 NULL); 00930 00931 /* Open the file */ 00932 Status = NtOpenFile (&FileHandle, 00933 SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, 00934 &ObjectAttributes, 00935 &IoStatusBlock, 00936 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 00937 FILE_SYNCHRONOUS_IO_NONALERT); 00938 RtlFreeUnicodeString (&FileName); 00939 if (!NT_SUCCESS (Status)) 00940 { 00941 WARN ("NtOpenFile() failed (Status %lx)\n", Status); 00942 BaseSetLastNTError (Status); 00943 return FALSE; 00944 } 00945 00946 Status = NtQueryInformationFile(FileHandle, 00947 &IoStatusBlock, 00948 &FileInformation, 00949 sizeof(FILE_BASIC_INFORMATION), 00950 FileBasicInformation); 00951 if (!NT_SUCCESS(Status)) 00952 { 00953 WARN ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status); 00954 NtClose (FileHandle); 00955 BaseSetLastNTError (Status); 00956 return FALSE; 00957 } 00958 00959 FileInformation.FileAttributes = dwFileAttributes; 00960 Status = NtSetInformationFile(FileHandle, 00961 &IoStatusBlock, 00962 &FileInformation, 00963 sizeof(FILE_BASIC_INFORMATION), 00964 FileBasicInformation); 00965 NtClose (FileHandle); 00966 if (!NT_SUCCESS(Status)) 00967 { 00968 WARN ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status); 00969 BaseSetLastNTError (Status); 00970 return FALSE; 00971 } 00972 00973 return TRUE; 00974 } 00975 00976 /* 00977 * @implemented 00978 */ 00979 BOOL WINAPI 00980 GetFileTime(IN HANDLE hFile, 00981 OUT LPFILETIME lpCreationTime OPTIONAL, 00982 OUT LPFILETIME lpLastAccessTime OPTIONAL, 00983 OUT LPFILETIME lpLastWriteTime OPTIONAL) 00984 { 00985 NTSTATUS Status; 00986 IO_STATUS_BLOCK IoStatusBlock; 00987 FILE_BASIC_INFORMATION FileBasic; 00988 00989 if(IsConsoleHandle(hFile)) 00990 { 00991 BaseSetLastNTError(STATUS_INVALID_HANDLE); 00992 return FALSE; 00993 } 00994 00995 Status = NtQueryInformationFile(hFile, 00996 &IoStatusBlock, 00997 &FileBasic, 00998 sizeof(FILE_BASIC_INFORMATION), 00999 FileBasicInformation); 01000 if (!NT_SUCCESS(Status)) 01001 { 01002 BaseSetLastNTError(Status); 01003 return FALSE; 01004 } 01005 01006 if (lpCreationTime) 01007 { 01008 lpCreationTime->dwLowDateTime = FileBasic.CreationTime.LowPart; 01009 lpCreationTime->dwHighDateTime = FileBasic.CreationTime.HighPart; 01010 } 01011 01012 if (lpLastAccessTime) 01013 { 01014 lpLastAccessTime->dwLowDateTime = FileBasic.LastAccessTime.LowPart; 01015 lpLastAccessTime->dwHighDateTime = FileBasic.LastAccessTime.HighPart; 01016 } 01017 01018 if (lpLastWriteTime) 01019 { 01020 lpLastWriteTime->dwLowDateTime = FileBasic.LastWriteTime.LowPart; 01021 lpLastWriteTime->dwHighDateTime = FileBasic.LastWriteTime.HighPart; 01022 } 01023 01024 return TRUE; 01025 } 01026 01027 01028 /* 01029 * @implemented 01030 */ 01031 BOOL WINAPI 01032 SetFileTime(IN HANDLE hFile, 01033 CONST FILETIME *lpCreationTime OPTIONAL, 01034 CONST FILETIME *lpLastAccessTime OPTIONAL, 01035 CONST FILETIME *lpLastWriteTime OPTIONAL) 01036 { 01037 NTSTATUS Status; 01038 IO_STATUS_BLOCK IoStatusBlock; 01039 FILE_BASIC_INFORMATION FileBasic; 01040 01041 if(IsConsoleHandle(hFile)) 01042 { 01043 BaseSetLastNTError(STATUS_INVALID_HANDLE); 01044 return FALSE; 01045 } 01046 01047 memset(&FileBasic, 0, sizeof(FILE_BASIC_INFORMATION)); 01048 01049 if (lpCreationTime) 01050 { 01051 FileBasic.CreationTime.LowPart = lpCreationTime->dwLowDateTime; 01052 FileBasic.CreationTime.HighPart = lpCreationTime->dwHighDateTime; 01053 } 01054 01055 if (lpLastAccessTime) 01056 { 01057 FileBasic.LastAccessTime.LowPart = lpLastAccessTime->dwLowDateTime; 01058 FileBasic.LastAccessTime.HighPart = lpLastAccessTime->dwHighDateTime; 01059 } 01060 01061 if (lpLastWriteTime) 01062 { 01063 FileBasic.LastWriteTime.LowPart = lpLastWriteTime->dwLowDateTime; 01064 FileBasic.LastWriteTime.HighPart = lpLastWriteTime->dwHighDateTime; 01065 } 01066 01067 Status = NtSetInformationFile(hFile, 01068 &IoStatusBlock, 01069 &FileBasic, 01070 sizeof(FILE_BASIC_INFORMATION), 01071 FileBasicInformation); 01072 if (!NT_SUCCESS(Status)) 01073 { 01074 BaseSetLastNTError(Status); 01075 return FALSE; 01076 } 01077 01078 return TRUE; 01079 } 01080 01081 01082 /* 01083 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set. 01084 * 01085 * @implemented 01086 */ 01087 BOOL WINAPI 01088 SetEndOfFile(HANDLE hFile) 01089 { 01090 IO_STATUS_BLOCK IoStatusBlock; 01091 FILE_END_OF_FILE_INFORMATION EndOfFileInfo; 01092 FILE_ALLOCATION_INFORMATION FileAllocationInfo; 01093 FILE_POSITION_INFORMATION FilePosInfo; 01094 NTSTATUS Status; 01095 01096 if(IsConsoleHandle(hFile)) 01097 { 01098 SetLastError(ERROR_INVALID_HANDLE); 01099 return FALSE; 01100 } 01101 01102 //get current position 01103 Status = NtQueryInformationFile( 01104 hFile, 01105 &IoStatusBlock, 01106 &FilePosInfo, 01107 sizeof(FILE_POSITION_INFORMATION), 01108 FilePositionInformation 01109 ); 01110 01111 if (!NT_SUCCESS(Status)){ 01112 BaseSetLastNTError(Status); 01113 return FALSE; 01114 } 01115 01116 EndOfFileInfo.EndOfFile.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart; 01117 01118 /* 01119 NOTE: 01120 This call is not supposed to free up any space after the eof marker 01121 if the file gets truncated. We have to deallocate the space explicitly afterwards. 01122 But...most file systems dispatch both FileEndOfFileInformation 01123 and FileAllocationInformation as they were the same command. 01124 01125 */ 01126 Status = NtSetInformationFile( 01127 hFile, 01128 &IoStatusBlock, //out 01129 &EndOfFileInfo, 01130 sizeof(FILE_END_OF_FILE_INFORMATION), 01131 FileEndOfFileInformation 01132 ); 01133 01134 if (!NT_SUCCESS(Status)){ 01135 BaseSetLastNTError(Status); 01136 return FALSE; 01137 } 01138 01139 FileAllocationInfo.AllocationSize.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart; 01140 01141 01142 Status = NtSetInformationFile( 01143 hFile, 01144 &IoStatusBlock, //out 01145 &FileAllocationInfo, 01146 sizeof(FILE_ALLOCATION_INFORMATION), 01147 FileAllocationInformation 01148 ); 01149 01150 if (!NT_SUCCESS(Status)){ 01151 BaseSetLastNTError(Status); 01152 return FALSE; 01153 } 01154 01155 return TRUE; 01156 01157 } 01158 01159 01160 /* 01161 * @implemented 01162 */ 01163 BOOL 01164 WINAPI 01165 SetFileValidData( 01166 HANDLE hFile, 01167 LONGLONG ValidDataLength 01168 ) 01169 { 01170 IO_STATUS_BLOCK IoStatusBlock; 01171 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation; 01172 NTSTATUS Status; 01173 01174 ValidDataLengthInformation.ValidDataLength.QuadPart = ValidDataLength; 01175 01176 Status = NtSetInformationFile( 01177 hFile, 01178 &IoStatusBlock, //out 01179 &ValidDataLengthInformation, 01180 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION), 01181 FileValidDataLengthInformation 01182 ); 01183 01184 if (!NT_SUCCESS(Status)){ 01185 BaseSetLastNTError(Status); 01186 return FALSE; 01187 } 01188 01189 return TRUE; 01190 } 01191 01192 /* EOF */ Generated on Sun May 27 2012 04:24:26 for ReactOS by
1.7.6.1
|