📄 file.c
字号:
for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++;
unique &= 0xffff;
if (unique) swprintf( p, formatW, unique );
else
{
/* get a "random" unique number and try to create the file */
HANDLE handle;
UINT num = GetTickCount() & 0xffff;
if (!num) num = 1;
unique = num;
do
{
swprintf( p, formatW, unique );
handle = CreateFileW( buffer, GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
if (handle != INVALID_HANDLE_VALUE)
{ /* We created it */
DPRINT("created %S\n", buffer);
CloseHandle( handle );
break;
}
if (GetLastError() != ERROR_FILE_EXISTS &&
GetLastError() != ERROR_SHARING_VIOLATION)
break; /* No need to go on */
if (!(++unique & 0xffff)) unique = 1;
} while (unique != num);
}
DPRINT("returning %S\n", buffer);
return unique;
}
/*
* @implemented
*/
BOOL STDCALL
GetFileTime(HANDLE hFile,
LPFILETIME lpCreationTime,
LPFILETIME lpLastAccessTime,
LPFILETIME lpLastWriteTime)
{
IO_STATUS_BLOCK IoStatusBlock;
FILE_BASIC_INFORMATION FileBasic;
NTSTATUS Status;
if(IsConsoleHandle(hFile))
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
Status = NtQueryInformationFile(hFile,
&IoStatusBlock,
&FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
if (lpCreationTime)
memcpy(lpCreationTime, &FileBasic.CreationTime, sizeof(FILETIME));
if (lpLastAccessTime)
memcpy(lpLastAccessTime, &FileBasic.LastAccessTime, sizeof(FILETIME));
if (lpLastWriteTime)
memcpy(lpLastWriteTime, &FileBasic.LastWriteTime, sizeof(FILETIME));
return TRUE;
}
/*
* @implemented
*/
BOOL STDCALL
SetFileTime(HANDLE hFile,
CONST FILETIME *lpCreationTime,
CONST FILETIME *lpLastAccessTime,
CONST FILETIME *lpLastWriteTime)
{
FILE_BASIC_INFORMATION FileBasic;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
if(IsConsoleHandle(hFile))
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
Status = NtQueryInformationFile(hFile,
&IoStatusBlock,
&FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
if (lpCreationTime)
memcpy(&FileBasic.CreationTime, lpCreationTime, sizeof(FILETIME));
if (lpLastAccessTime)
memcpy(&FileBasic.LastAccessTime, lpLastAccessTime, sizeof(FILETIME));
if (lpLastWriteTime)
memcpy(&FileBasic.LastWriteTime, lpLastWriteTime, sizeof(FILETIME));
// should i initialize changetime ???
Status = NtSetInformationFile(hFile,
&IoStatusBlock,
&FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
return TRUE;
}
/*
* The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
*
* @implemented
*/
BOOL STDCALL
SetEndOfFile(HANDLE hFile)
{
IO_STATUS_BLOCK IoStatusBlock;
FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
FILE_ALLOCATION_INFORMATION FileAllocationInfo;
FILE_POSITION_INFORMATION FilePosInfo;
NTSTATUS Status;
if(IsConsoleHandle(hFile))
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
//get current position
Status = NtQueryInformationFile(
hFile,
&IoStatusBlock,
&FilePosInfo,
sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation
);
if (!NT_SUCCESS(Status)){
SetLastErrorByStatus(Status);
return FALSE;
}
EndOfFileInfo.EndOfFile.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
/*
NOTE:
This call is not supposed to free up any space after the eof marker
if the file gets truncated. We have to deallocate the space explicitly afterwards.
But...most file systems dispatch both FileEndOfFileInformation
and FileAllocationInformation as they were the same command.
*/
Status = NtSetInformationFile(
hFile,
&IoStatusBlock, //out
&EndOfFileInfo,
sizeof(FILE_END_OF_FILE_INFORMATION),
FileEndOfFileInformation
);
if (!NT_SUCCESS(Status)){
SetLastErrorByStatus(Status);
return FALSE;
}
FileAllocationInfo.AllocationSize.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
Status = NtSetInformationFile(
hFile,
&IoStatusBlock, //out
&FileAllocationInfo,
sizeof(FILE_ALLOCATION_INFORMATION),
FileAllocationInformation
);
if (!NT_SUCCESS(Status)){
SetLastErrorByStatus(Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL
STDCALL
SetFileValidData(
HANDLE hFile,
LONGLONG ValidDataLength
)
{
IO_STATUS_BLOCK IoStatusBlock;
FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation;
NTSTATUS Status;
ValidDataLengthInformation.ValidDataLength.QuadPart = ValidDataLength;
Status = NtSetInformationFile(
hFile,
&IoStatusBlock, //out
&ValidDataLengthInformation,
sizeof(FILE_VALID_DATA_LENGTH_INFORMATION),
FileValidDataLengthInformation
);
if (!NT_SUCCESS(Status)){
SetLastErrorByStatus(Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL
STDCALL
SetFileShortNameW(
HANDLE hFile,
LPCWSTR lpShortName)
{
NTSTATUS Status;
ULONG NeededSize;
UNICODE_STRING ShortName;
IO_STATUS_BLOCK IoStatusBlock;
PFILE_NAME_INFORMATION FileNameInfo;
if(IsConsoleHandle(hFile))
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if(!lpShortName)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
RtlInitUnicodeString(&ShortName, lpShortName);
NeededSize = sizeof(FILE_NAME_INFORMATION) + ShortName.Length + sizeof(WCHAR);
if(!(FileNameInfo = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize)))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
FileNameInfo->FileNameLength = ShortName.Length;
RtlCopyMemory(FileNameInfo->FileName, ShortName.Buffer, ShortName.Length);
Status = NtSetInformationFile(hFile,
&IoStatusBlock, //out
FileNameInfo,
NeededSize,
FileShortNameInformation);
RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInfo);
if(!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL
STDCALL
SetFileShortNameA(
HANDLE hFile,
LPCSTR lpShortName
)
{
PWCHAR ShortNameW;
if(IsConsoleHandle(hFile))
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if(!lpShortName)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!(ShortNameW = FilenameA2W(lpShortName, FALSE)))
return FALSE;
return SetFileShortNameW(hFile, ShortNameW);
}
/*
* @implemented
*/
BOOL
STDCALL
CheckNameLegalDOS8Dot3W(
LPCWSTR lpName,
LPSTR lpOemName OPTIONAL,
DWORD OemNameSize OPTIONAL,
PBOOL pbNameContainsSpaces OPTIONAL,
PBOOL pbNameLegal
)
{
UNICODE_STRING Name;
ANSI_STRING AnsiName;
if(lpName == NULL ||
(lpOemName == NULL && OemNameSize != 0) ||
pbNameLegal == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if(lpOemName != NULL)
{
AnsiName.Buffer = lpOemName;
AnsiName.MaximumLength = OemNameSize * sizeof(CHAR);
AnsiName.Length = 0;
}
RtlInitUnicodeString(&Name, lpName);
*pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name,
(lpOemName ? &AnsiName : NULL),
(BOOLEAN*)pbNameContainsSpaces);
return TRUE;
}
/*
* @implemented
*/
BOOL
STDCALL
CheckNameLegalDOS8Dot3A(
LPCSTR lpName,
LPSTR lpOemName OPTIONAL,
DWORD OemNameSize OPTIONAL,
PBOOL pbNameContainsSpaces OPTIONAL,
PBOOL pbNameLegal
)
{
UNICODE_STRING Name;
ANSI_STRING AnsiName, AnsiInputName;
NTSTATUS Status;
if(lpName == NULL ||
(lpOemName == NULL && OemNameSize != 0) ||
pbNameLegal == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if(lpOemName != NULL)
{
AnsiName.Buffer = lpOemName;
AnsiName.MaximumLength = OemNameSize * sizeof(CHAR);
AnsiName.Length = 0;
}
RtlInitAnsiString(&AnsiInputName, (LPSTR)lpName);
if(bIsFileApiAnsi)
Status = RtlAnsiStringToUnicodeString(&Name, &AnsiInputName, TRUE);
else
Status = RtlOemStringToUnicodeString(&Name, &AnsiInputName, TRUE);
if(!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
*pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name,
(lpOemName ? &AnsiName : NULL),
(BOOLEAN*)pbNameContainsSpaces);
RtlFreeUnicodeString(&Name);
return TRUE;
}
/*
* @implemented
*/
DWORD
WINAPI
GetFinalPathNameByHandleA(IN HANDLE hFile,
OUT LPSTR lpszFilePath,
IN DWORD cchFilePath,
IN DWORD dwFlags)
{
WCHAR FilePathW[MAX_PATH];
UNICODE_STRING FilePathU;
DWORD PrevLastError;
DWORD Ret = 0;
if (cchFilePath != 0 &&
cchFilePath > sizeof(FilePathW) / sizeof(FilePathW[0]))
{
FilePathU.Length = 0;
FilePathU.MaximumLength = cchFilePath * sizeof(WCHAR);
FilePathU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
0,
FilePathU.MaximumLength);
if (FilePathU.Buffer == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
}
else
{
FilePathU.Length = 0;
FilePathU.MaximumLength = sizeof(FilePathW);
FilePathU.Buffer = FilePathW;
}
/* save the last error code */
PrevLastError = GetLastError();
SetLastError(ERROR_SUCCESS);
/* call the unicode version that does all the work */
Ret = GetFinalPathNameByHandleW(hFile,
FilePathU.Buffer,
cchFilePath,
dwFlags);
if (GetLastError() == ERROR_SUCCESS)
{
/* no error, restore the last error code and convert the string */
SetLastError(PrevLastError);
Ret = FilenameU2A_FitOrFail(lpszFilePath,
cchFilePath,
&FilePathU);
}
/* free allocated memory if necessary */
if (FilePathU.Buffer != FilePathW)
{
RtlFreeHeap(RtlGetProcessHeap(),
0,
FilePathU.Buffer);
}
return Ret;
}
/*
* @unimplemented
*/
DWORD
WINAPI
GetFinalPathNameByHandleW(IN HANDLE hFile,
OUT LPWSTR lpszFilePath,
IN DWORD cchFilePath,
IN DWORD dwFlags)
{
if (dwFlags & ~(VOLUME_NAME_DOS | VOLUME_NAME_GUID | VOLUME_NAME_NT |
VOLUME_NAME_NONE | FILE_NAME_NORMALIZED | FILE_NAME_OPENED))
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
BOOL
WINAPI
SetFileBandwidthReservation(IN HANDLE hFile,
IN DWORD nPeriodMilliseconds,
IN DWORD nBytesPerPeriod,
IN BOOL bDiscardable,
OUT LPDWORD lpTransferSize,
OUT LPDWORD lpNumOutstandingRequests)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
GetFileBandwidthReservation(IN HANDLE hFile,
OUT LPDWORD lpPeriodMilliseconds,
OUT LPDWORD lpBytesPerPeriod,
OUT LPBOOL pDiscardable,
OUT LPDWORD lpTransferSize,
OUT LPDWORD lpNumOutstandingRequests)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
SetFileCompletionNotificationModes(IN HANDLE FileHandle,
IN UCHAR Flags)
{
if (Flags & ~(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS | FILE_SKIP_SET_EVENT_ON_HANDLE))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
HANDLE
WINAPI
OpenFileById(IN HANDLE hFile,
IN LPFILE_ID_DESCRIPTOR lpFileID,
IN DWORD dwDesiredAccess,
IN DWORD dwShareMode,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL,
IN DWORD dwFlags)
{
UNIMPLEMENTED;
return INVALID_HANDLE_VALUE;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -