Пример #1
0
// PELF_FILE_SET_SIZE_ROUTINE
static
NTSTATUS NTAPI
LogfpSetFileSize(IN PEVTLOGFILE LogFile,
                 IN ULONG FileSize,    // SIZE_T
                 IN ULONG OldFileSize) // SIZE_T
{
    NTSTATUS Status;
    PLOGFILE pLogFile = (PLOGFILE)LogFile;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_END_OF_FILE_INFORMATION FileEofInfo;
    FILE_ALLOCATION_INFORMATION FileAllocInfo;

    UNREFERENCED_PARAMETER(OldFileSize);

    // FIXME: Should we round up FileSize ??

    FileEofInfo.EndOfFile.QuadPart = FileSize;
    Status = NtSetInformationFile(pLogFile->FileHandle,
                                  &IoStatusBlock,
                                  &FileEofInfo,
                                  sizeof(FileEofInfo),
                                  FileEndOfFileInformation);
    if (!NT_SUCCESS(Status))
        return Status;

    FileAllocInfo.AllocationSize.QuadPart = FileSize;
    Status = NtSetInformationFile(pLogFile->FileHandle,
                                  &IoStatusBlock,
                                  &FileAllocInfo,
                                  sizeof(FileAllocInfo),
                                  FileAllocationInformation);

    return Status;
}
Пример #2
0
NTSTATUS NtDeleteFile2(POBJECT_ATTRIBUTES ObjectAttributes)
{
	HANDLE hFile;

	IO_STATUS_BLOCK IoStatusBlock;

	auto Status = NtOpenFile(&hFile, SYNCHRONIZE | DELETE, ObjectAttributes, &IoStatusBlock, FILE_SHARE_DELETE | FILE_SHARE_READ, FILE_OPEN_REPARSE_POINT | FILE_OPEN_FOR_BACKUP_INTENT);

	if (Status)
	{
		return Status;
	}

	FILE_DISPOSITION_INFORMATION Dispostion = { TRUE };

	Status = NtSetInformationFile(hFile, &IoStatusBlock, &Dispostion, sizeof(Dispostion), FileDispositionInformation);

	NtClose(hFile);

	if (Status == 0)
		return 0;

	//使用文件取代法删除
	auto cbData = ObjectAttributes->ObjectName->Length + sizeof(L"~$") - 2;
	UNICODE_STRING TempFileName = { cbData,cbData, (wchar_t*)new byte[cbData] };

	memcpy(TempFileName.Buffer, ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length);
	*(wchar_t*)(((byte*)TempFileName.Buffer) + ObjectAttributes->ObjectName->Length) = L'~';
	*(wchar_t*)(((byte*)TempFileName.Buffer) + ObjectAttributes->ObjectName->Length + 2) = L'$';


	OBJECT_ATTRIBUTES ObjectAttributes2 = { sizeof(OBJECT_ATTRIBUTES),ObjectAttributes->RootDirectory, &TempFileName, OBJ_CASE_INSENSITIVE };

	auto Status2 = NtCreateFile(&hFile, SYNCHRONIZE | DELETE, &ObjectAttributes2, &IoStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_OPEN_FOR_BACKUP_INTENT | FILE_DELETE_ON_CLOSE, NULL, 0);

	delete[](byte*)TempFileName.Buffer;


	cbData = sizeof(FILE_RENAME_INFORMATION) + ObjectAttributes->ObjectName->Length;

	FILE_RENAME_INFORMATION* pRenameInfo = (FILE_RENAME_INFORMATION*)new byte[cbData];

	memcpy(pRenameInfo->FileName, ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length);
	pRenameInfo->ReplaceIfExists = TRUE;
	pRenameInfo->RootDirectory = ObjectAttributes->RootDirectory;
	pRenameInfo->FileNameLength = ObjectAttributes->ObjectName->Length;
	//FILE_RENAME_INFORMATION RenameInfo = {TRUE,hRootDir ,FileName.};

	Status2 = NtSetInformationFile(hFile, &IoStatusBlock, pRenameInfo, cbData, FileRenameInformation);

	delete[](byte*)pRenameInfo;

	NtClose(hFile);

	return Status2 == 0 ? 0 : Status;
}
Пример #3
0
static int winfs_link(struct mount_point *mp, struct file *f, const char *newpath)
{
	AcquireSRWLockShared(&f->rw_lock);
	struct winfs_file *winfile = (struct winfs_file *) f;
	NTSTATUS status;
	int r = 0;
	char buf[sizeof(FILE_LINK_INFORMATION) + PATH_MAX * 2];
	FILE_LINK_INFORMATION *info = (FILE_LINK_INFORMATION *)buf;
	info->ReplaceIfExists = FALSE;
	info->RootDirectory = NULL;
	info->FileNameLength = 2 * filename_to_nt_pathname(mp, newpath, info->FileName, PATH_MAX);
	if (info->FileNameLength == 0)
	{
		r = -L_ENOENT;
		goto out;
	}
	IO_STATUS_BLOCK status_block;
	status = NtSetInformationFile(winfile->handle, &status_block, info, info->FileNameLength + sizeof(FILE_LINK_INFORMATION), FileLinkInformation);
	if (!NT_SUCCESS(status))
	{
		log_warning("NtSetInformationFile() failed, status: %x.", status);
		r = -L_ENOENT;
		goto out;
	}
out:
	ReleaseSRWLockShared(&f->rw_lock);
	return r;
}
Пример #4
0
VOID SetupDeleteDirectoryFile(_In_ PWSTR FileName)
{
    HANDLE tempHandle;
    FILE_DISPOSITION_INFORMATION dispositionInfo;
    IO_STATUS_BLOCK isb;

    if (NT_SUCCESS(PhCreateFileWin32(
        &tempHandle,
        FileName,
        FILE_GENERIC_WRITE | DELETE,
        0,
        0,
        FILE_OVERWRITE_IF,
        FILE_SYNCHRONOUS_IO_NONALERT
        )))
    {
        dispositionInfo.DeleteFile = TRUE;
        NtSetInformationFile(
            tempHandle,
            &isb,
            &dispositionInfo,
            sizeof(FILE_DISPOSITION_INFORMATION),
            FileDispositionInformation
            );
        NtClose(tempHandle);
    }
}
Пример #5
0
static NTSTATUS
SetLastWriteTime(
	HANDLE FileHandle,
	LARGE_INTEGER LastWriteTime
	)
{
   NTSTATUS errCode = STATUS_SUCCESS;
   IO_STATUS_BLOCK IoStatusBlock;
   FILE_BASIC_INFORMATION FileBasic;

   errCode = NtQueryInformationFile (FileHandle,
				     &IoStatusBlock,
				     &FileBasic,
				     sizeof(FILE_BASIC_INFORMATION),
				     FileBasicInformation);
   if (!NT_SUCCESS(errCode))
     {
	WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode);
     }
   else
     {
	FileBasic.LastWriteTime.QuadPart = LastWriteTime.QuadPart;
	errCode = NtSetInformationFile (FileHandle,
					&IoStatusBlock,
					&FileBasic,
					sizeof(FILE_BASIC_INFORMATION),
					FileBasicInformation);
	if (!NT_SUCCESS(errCode))
	  {
	     WARN("Error 0x%0x setting LastWriteTime\n", errCode);
	  }
     }

   return errCode;
}
Пример #6
0
NTSTATUS
BowserDebugCall(
    IN PLMDR_REQUEST_PACKET InputBuffer,
    IN ULONG InputBufferLength
    )
{
    NTSTATUS Status;

    PAGED_CODE();

    ASSERT (IoGetCurrentProcess() == BowserFspProcess);

    if (InputBufferLength < sizeof(LMDR_REQUEST_PACKET)) {
        return STATUS_BUFFER_TOO_SMALL;
    }

    if (InputBuffer->Version != LMDR_REQUEST_PACKET_VERSION) {
        return (Status = STATUS_INVALID_PARAMETER);
    }

    if (InputBuffer->Parameters.Debug.OpenLog && InputBuffer->Parameters.Debug.CloseLog) {
        return (Status = STATUS_INVALID_PARAMETER);
    }

    if (InputBuffer->Parameters.Debug.OpenLog) {
        Status = BowserOpenTraceLogFile(InputBuffer->Parameters.Debug.TraceFileName);
        return Status;
    } else if (InputBuffer->Parameters.Debug.CloseLog) {
        Status = ZwClose(BrowserTraceLogHandle);

        if (NT_SUCCESS(Status)) {
            BrowserTraceLogHandle = NULL;
        }

        return Status;
    } else if (InputBuffer->Parameters.Debug.TruncateLog) {
        FILE_END_OF_FILE_INFORMATION EndOfFileInformation;
        IO_STATUS_BLOCK IoStatus;

        if (BrowserTraceLogHandle == NULL) {
            return STATUS_INVALID_HANDLE;
        }

        EndOfFileInformation.EndOfFile.HighPart = 0;
        EndOfFileInformation.EndOfFile.LowPart = 0;

        Status = NtSetInformationFile(BrowserTraceLogHandle,
                                        &IoStatus,
                                        &EndOfFileInformation,
                                        sizeof(EndOfFileInformation),
                                        FileEndOfFileInformation);

        return Status;
    } else {
        BowserDebugTraceLevel = InputBuffer->Parameters.Debug.DebugTraceBits;
        KdPrint(("Setting Browser Debug Trace Bits to %lx\n", BowserDebugTraceLevel));
    }

    return STATUS_SUCCESS;
}
/** Windows/NT worker.
 * @todo rename to rtFileWinSetAttributes */
int rtFileNativeSetAttributes(HANDLE hFile, ULONG fAttributes)
{
    IO_STATUS_BLOCK IoStatusBlock;
    memset(&IoStatusBlock, 0, sizeof(IoStatusBlock));

    /*
     * Members that are set 0 will not be modified on the file object.
     * See http://msdn.microsoft.com/en-us/library/aa491634.aspx (the struct docs)
     * for details.
     */
    FILE_BASIC_INFORMATION Info;
    memset(&Info, 0, sizeof(Info));
    Info.FileAttributes = fAttributes;

#if 0
    /** @todo resolve dynamically to avoid dragging in NtDll? */
    NTSTATUS Status = NtSetInformationFile(hFile,
                                           &IoStatusBlock,
                                           &Info,
                                           sizeof(Info),
                                           FileBasicInformation);

    return RtlNtStatusToDosError(Status);
#endif
    return 1;
}
Пример #8
0
int XSetFilePointer(
	int handle,
	int distanceToMove,
	int *newFilePointer,
	int moveMethod)
{
	FILE_POSITION_INFORMATION positionInfo;
	LARGE_INTEGER             targetPointer;
	IO_STATUS_BLOCK           ioStatusBlock;
	NTSTATUS                  status;
	int                       filesize;
	
#ifdef DEBUG
	debugPrint("XSetFilePointer handle=%08x distance=%08x method=%02x\n", handle, distanceToMove, moveMethod);
#endif

	// Calculate the target pointer
	switch (moveMethod)
	{
	case FILE_BEGIN:      // From the beginning of the file
		targetPointer.u.HighPart = 0;
		targetPointer.u.LowPart = distanceToMove;
	  break;
	case FILE_CURRENT:    // From the current position
		status = NtQueryInformationFile((void*)handle, &ioStatusBlock, &positionInfo, sizeof(positionInfo), FilePositionInformation);
		if (!NT_SUCCESS(status))
			return RtlNtStatusToDosError(status);
		targetPointer.u.HighPart = 0;
		targetPointer.u.LowPart = positionInfo.CurrentByteOffset.u.LowPart + distanceToMove;
		break;
	case FILE_END:       // From the end of the file
		status = XGetFileSize(handle, &filesize);
		if (!NT_SUCCESS(status))
			return RtlNtStatusToDosError(status);
		targetPointer.u.HighPart = 0;
		targetPointer.u.LowPart -= distanceToMove;
		break;
	default:
		return ERROR_INVALID_PARAMETER;
	}
	
	// Don't allow a negative seek
	if ((targetPointer.u.LowPart & 0x80000000) != 0)
		return ERROR_NEGATIVE_SEEK;
	
	// Fill in the new position information
	positionInfo.CurrentByteOffset.u.HighPart = targetPointer.u.HighPart;
	positionInfo.CurrentByteOffset.u.LowPart= targetPointer.u.LowPart;
	
	// Set the new position
	status = NtSetInformationFile((void*)handle, &ioStatusBlock, &positionInfo, sizeof(positionInfo), FilePositionInformation);
	if (!NT_SUCCESS(status))
		return RtlNtStatusToDosError(status);
	else
	{
		if (newFilePointer)
			*newFilePointer = targetPointer.u.LowPart;
		return STATUS_SUCCESS;
	}		
}
Пример #9
0
static int winfs_open(struct file_system *fs, const char *pathname, int flags, int mode, struct file **fp, char *target, int buflen)
{
	/* TODO: mode */
	DWORD desired_access, create_disposition;
	HANDLE handle;

	if (flags & O_PATH)
		desired_access = 0;
	else if (flags & O_RDWR)
		desired_access = GENERIC_READ | GENERIC_WRITE;
	else if (flags & O_WRONLY)
		desired_access = GENERIC_WRITE;
	else
		desired_access = GENERIC_READ;
	if (flags & __O_DELETE)
		desired_access |= DELETE;
	if (flags & O_EXCL)
		create_disposition = FILE_CREATE;
	else if (flags & O_CREAT)
		create_disposition = FILE_OPEN_IF;
	else
		create_disposition = FILE_OPEN;
	int r = open_file(&handle, pathname, desired_access, create_disposition, flags, fp != NULL, target, buflen);
	if (r < 0 || r == 1)
		return r;
	if ((flags & O_TRUNC) && ((flags & O_WRONLY) || (flags & O_RDWR)))
	{
		/* Truncate the file */
		FILE_END_OF_FILE_INFORMATION info;
		info.EndOfFile.QuadPart = 0;
		IO_STATUS_BLOCK status_block;
		NTSTATUS status = NtSetInformationFile(handle, &status_block, &info, sizeof(info), FileEndOfFileInformation);
		if (!NT_SUCCESS(status))
			log_error("NtSetInformationFile() failed, status: %x", status);
	}

	if (fp)
	{
		int pathlen = strlen(pathname);
		struct winfs_file *file = (struct winfs_file *)kmalloc(sizeof(struct winfs_file) + pathlen);
		file_init(&file->base_file, &winfs_ops, flags);
		file->handle = handle;
		SECURITY_ATTRIBUTES attr;
		attr.nLength = sizeof(SECURITY_ATTRIBUTES);
		attr.bInheritHandle = TRUE;
		attr.lpSecurityDescriptor = NULL;
		/* TODO: Don't need this mutex for directory or symlink */
		file->fp_mutex = CreateMutexW(&attr, FALSE, NULL);
		file->restart_scan = 1;
		file->pathlen = pathlen;
		memcpy(file->pathname, pathname, pathlen);
		*fp = (struct file *)file;
	}
	else
		CloseHandle(handle);
	return 0;
}
Пример #10
0
static int winfs_unlink(struct mount_point *mp, const char *pathname)
{
	WCHAR wpathname[PATH_MAX];
	int len = filename_to_nt_pathname(mp, pathname, wpathname, PATH_MAX);
	if (len <= 0)
		return -L_ENOENT;

	UNICODE_STRING object_name;
	RtlInitCountedUnicodeString(&object_name, wpathname, len * sizeof(WCHAR));

	OBJECT_ATTRIBUTES attr;
	attr.Length = sizeof(OBJECT_ATTRIBUTES);
	attr.RootDirectory = NULL;
	attr.ObjectName = &object_name;
	attr.Attributes = 0;
	attr.SecurityDescriptor = NULL;
	attr.SecurityQualityOfService = NULL;
	IO_STATUS_BLOCK status_block;
	NTSTATUS status;
	HANDLE handle;
	status = NtOpenFile(&handle, DELETE, &attr, &status_block, FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT);
	if (!NT_SUCCESS(status))
	{
		if (status != STATUS_SHARING_VIOLATION)
		{
			log_warning("NtOpenFile() failed, status: %x", status);
			return -L_ENOENT;
		}
		/* This file has open handles in some processes, even we set delete disposition flags
		 * The actual deletion of the file will be delayed to the last handle closing
		 * To make the file disappear from its parent directory immediately, we move the file
		 * to Windows recycle bin prior to deletion.
		 */
		status = NtOpenFile(&handle, DELETE, &attr, &status_block, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
			FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT);
		if (!NT_SUCCESS(status))
		{
			log_warning("NtOpenFile() failed, status: %x", status);
			return -L_EBUSY;
		}
		status = move_to_recycle_bin(handle, wpathname);
		if (!NT_SUCCESS(status))
			return -L_EBUSY;
	}
	/* Set disposition flag */
	FILE_DISPOSITION_INFORMATION info;
	info.DeleteFile = TRUE;
	status = NtSetInformationFile(handle, &status_block, &info, sizeof(info), FileDispositionInformation);
	if (!NT_SUCCESS(status))
	{
		log_warning("NtSetInformation(FileDispositionInformation) failed, status: %x", status);
		return -L_EBUSY;
	}
	NtClose(handle);
	return 0;
}
Пример #11
0
int XDeleteDirectory(char *directoryName)
{
	ANSI_STRING                  xboxFilename;
	IO_STATUS_BLOCK              ioStatusBlock;
	OBJECT_ATTRIBUTES            objectAttributes;
	FILE_DISPOSITION_INFORMATION deleteInfo;
	NTSTATUS                     status;
	int                          handle;

#ifdef DEBUG
	debugPrint("XDeleteDirectory directoryName=%s\n", directoryName);
#endif

	char tmp[200];
	int rc = XConvertDOSFilenameToXBOX(directoryName, tmp);
	if (rc != STATUS_SUCCESS)
		return rc;
	RtlInitAnsiString(&xboxFilename, tmp);

	objectAttributes.RootDirectory = NULL;
	objectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
	objectAttributes.ObjectName = &xboxFilename;

	// Open the file for deletion
	status = NtCreateFile(
		(PHANDLE)&handle, 
		DELETE | SYNCHRONIZE, 
		&objectAttributes,
		&ioStatusBlock, 
		NULL, 
		0, 
		FILE_SHARE_DELETE, 
		FILE_OPEN,
		FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
		
	if (!NT_SUCCESS(status))
		return RtlNtStatusToDosError(status);
		
	// Delete the file
	deleteInfo.DeleteFile = TRUE;
	status = NtSetInformationFile(
		(HANDLE)handle, 
		&ioStatusBlock, 
		&deleteInfo,
		sizeof(deleteInfo), 
		FileDispositionInformation);

	if (!NT_SUCCESS(status))
		return RtlNtStatusToDosError(status);
	else
	{
		// Close the dead handle and return
		NtClose((HANDLE)handle);
		return STATUS_SUCCESS;
	}
}
Пример #12
0
BOOL
APIENTRY
SetMailslotInfo(
    IN HANDLE hMailslot,
    IN DWORD lReadTimeout
    )

/*++

Routine Description:

    This function will set the read timeout for the specified mailslot.

Arguments:

    hMailslot - A handle to the mailslot.

    lReadTimeout - The new read timeout, in milliseconds.

Return Value:

    TRUE - The operation was successful.

    FALSE/NULL - The operation failed. Extended error status is available
        using GetLastError.

--*/

{
    NTSTATUS status;
    IO_STATUS_BLOCK ioStatusBlock;
    FILE_MAILSLOT_SET_INFORMATION mailslotInfo;
    LARGE_INTEGER timeout;

    if ( lReadTimeout == MAILSLOT_WAIT_FOREVER ) {
        timeout.HighPart = 0x7FFFFFFF;
        timeout.LowPart = 0xFFFFFFFF;
    } else {
        timeout.QuadPart = - (LONGLONG)UInt32x32To64( lReadTimeout, 10 * 1000 );
    }

    mailslotInfo.ReadTimeout = &timeout;
    status = NtSetInformationFile( hMailslot,
                                   &ioStatusBlock,
                                   &mailslotInfo,
                                   sizeof( mailslotInfo ),
                                   FileMailslotSetInformation );

    if ( !NT_SUCCESS( status ) ) {
        BaseSetLastNTError( status );
        return ( FALSE );
    }

    return TRUE;
}
Пример #13
0
/*
 * @implemented
 */
VOID
WINAPI
BaseMarkFileForDelete(IN HANDLE FileHandle,
                      IN ULONG FileAttributes)
{
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_BASIC_INFORMATION FileBasicInfo;
    FILE_DISPOSITION_INFORMATION FileDispositionInfo;

    /* If no attributes were given, get them */
    if (!FileAttributes)
    {
        FileBasicInfo.FileAttributes = 0;
        NtQueryInformationFile(FileHandle,
                               &IoStatusBlock,
                               &FileBasicInfo,
                               sizeof(FileBasicInfo),
                               FileBasicInformation);
        FileAttributes = FileBasicInfo.FileAttributes;
    }

    /* If file is marked as RO, reset its attributes */
    if (FileAttributes & FILE_ATTRIBUTE_READONLY)
    {
        RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
        FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
        NtSetInformationFile(FileHandle,
                             &IoStatusBlock,
                             &FileBasicInfo,
                             sizeof(FileBasicInfo),
                             FileBasicInformation);
    }

    /* Finally, mark the file for deletion */
    FileDispositionInfo.DeleteFile = TRUE;
    NtSetInformationFile(FileHandle,
                         &IoStatusBlock,
                         &FileDispositionInfo,
                         sizeof(FileDispositionInfo),
                         FileDispositionInformation);
}
Пример #14
0
NTSTATUS
NTAPI
SmpDeletePagingFile(IN PUNICODE_STRING FileName)
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    HANDLE FileHandle;
    FILE_DISPOSITION_INFORMATION Disposition;

    /* Open the page file */
    InitializeObjectAttributes(&ObjectAttributes,
                               FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenFile(&FileHandle,
                        DELETE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_NON_DIRECTORY_FILE);
    if (NT_SUCCESS(Status))
    {
        /* Delete it */
        Disposition.DeleteFile = TRUE;
        Status = NtSetInformationFile(FileHandle,
                                      &IoStatusBlock,
                                      &Disposition,
                                      sizeof(Disposition),
                                      FileDispositionInformation);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("SMSS:PFILE: Failed to delete page file `%wZ' (status %X)\n",
                    FileName, Status);
        }
        else
        {
            DPRINT1("SMSS:PFILE: Deleted stale paging file - %wZ\n", FileName);
        }

        /* Close the handle */
        NtClose(FileHandle);
    }
    else
    {
        DPRINT1("SMSS:PFILE: Failed to open for deletion page file `%wZ' (status %X)\n",
                FileName, Status);
    }

    /* All done */
    return Status;
}
Пример #15
0
static int winfs_open(struct file_system *fs, const char *pathname, int flags, int mode, struct file **fp, char *target, int buflen)
{
	/* TODO: mode */
	DWORD desired_access, create_disposition;
	HANDLE handle;

	if (flags & O_PATH)
		desired_access = 0;
	else if (flags & O_RDWR)
		desired_access = GENERIC_READ | GENERIC_WRITE;
	else if (flags & O_WRONLY)
		desired_access = GENERIC_WRITE;
	else
		desired_access = GENERIC_READ;
	if (flags & __O_DELETE)
		desired_access |= DELETE;
	if (flags & O_EXCL)
		create_disposition = FILE_CREATE;
	else if (flags & O_CREAT)
		create_disposition = FILE_OPEN_IF;
	else
		create_disposition = FILE_OPEN;
	int r = open_file(&handle, pathname, desired_access, create_disposition, flags, fp != NULL, target, buflen);
	if (r < 0 || r == 1)
		return r;
	if ((flags & O_TRUNC) && ((flags & O_WRONLY) || (flags & O_RDWR)))
	{
		/* Truncate the file */
		FILE_END_OF_FILE_INFORMATION info;
		info.EndOfFile.QuadPart = 0;
		IO_STATUS_BLOCK status_block;
		NTSTATUS status = NtSetInformationFile(handle, &status_block, &info, sizeof(info), FileEndOfFileInformation);
		if (!NT_SUCCESS(status))
			log_error("NtSetInformationFile() failed, status: %x\n", status);
	}

	if (fp)
	{
		int pathlen = strlen(pathname);
		struct winfs_file *file = (struct winfs_file *)kmalloc(sizeof(struct winfs_file) + pathlen);
		file->base_file.op_vtable = &winfs_ops;
		file->base_file.ref = 1;
		file->base_file.flags = flags;
		file->handle = handle;
		file->restart_scan = 1;
		file->pathlen = pathlen;
		memcpy(file->pathname, pathname, pathlen);
		*fp = (struct file *)file;
	}
	else
		CloseHandle(handle);
	return 0;
}
Пример #16
0
/*++
* @name SmpDeleteFile
*
* The SmpDeleteFile function deletes a specify file.
*
* @param    lpFileName
*           the name of a file which should be deleted
*
* @return   STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
*           othwerwise.
*
* @remarks
* This function is called by SmpMoveFilesQueryRoutine().
*
*
*--*/
NTSTATUS
SmpDeleteFile( IN LPCWSTR lpFileName )
{
	FILE_DISPOSITION_INFORMATION FileDispInfo;
	OBJECT_ATTRIBUTES ObjectAttributes;
	IO_STATUS_BLOCK IoStatusBlock;
	UNICODE_STRING FileNameU;
	HANDLE FileHandle;
	NTSTATUS Status;

	DPRINT("SmpDeleteFile ( %S )\n", lpFileName);

	if( !lpFileName )
		return (STATUS_INVALID_PARAMETER);

	RtlInitUnicodeString(&FileNameU, lpFileName);

	InitializeObjectAttributes(&ObjectAttributes,
		&FileNameU,
		OBJ_CASE_INSENSITIVE,
		NULL,
		NULL);

	Status = NtCreateFile (&FileHandle,
		DELETE,
		&ObjectAttributes,
		&IoStatusBlock,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		FILE_OPEN,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0);

	if( !NT_SUCCESS(Status) ) {
		DPRINT("NtCreateFile() failed (Status %lx)\n", Status);
		return (Status);
	}

	FileDispInfo.DeleteFile = TRUE;

	Status = NtSetInformationFile(
		FileHandle,
		&IoStatusBlock,
		&FileDispInfo,
		sizeof(FILE_DISPOSITION_INFORMATION),
		FileDispositionInformation );

	NtClose(FileHandle);

	return (Status);
}
Пример #17
0
/*
 * @implemented
 */
BOOL
WINAPI
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))
    {
        BaseSetLastNTError(Status);
        return FALSE;
    }

    return TRUE;
}
Пример #18
0
/*
 * FUNCTION: Sets attributes on a file
 * ARGUMENTS:
 *      File = Pointer to CFFILE node for file
 * RETURNS:
 *     Status of operation
 */
static BOOL
SetAttributesOnFile(PCFFILE File,
                    HANDLE hFile)
{
    FILE_BASIC_INFORMATION FileBasic;
    IO_STATUS_BLOCK IoStatusBlock;
    NTSTATUS NtStatus;
    ULONG Attributes = 0;

    if (File->Attributes & CAB_ATTRIB_READONLY)
        Attributes |= FILE_ATTRIBUTE_READONLY;

    if (File->Attributes & CAB_ATTRIB_HIDDEN)
        Attributes |= FILE_ATTRIBUTE_HIDDEN;

    if (File->Attributes & CAB_ATTRIB_SYSTEM)
        Attributes |= FILE_ATTRIBUTE_SYSTEM;

    if (File->Attributes & CAB_ATTRIB_DIRECTORY)
        Attributes |= FILE_ATTRIBUTE_DIRECTORY;

    if (File->Attributes & CAB_ATTRIB_ARCHIVE)
        Attributes |= FILE_ATTRIBUTE_ARCHIVE;

    NtStatus = NtQueryInformationFile(hFile,
                                      &IoStatusBlock,
                                      &FileBasic,
                                      sizeof(FILE_BASIC_INFORMATION),
                                      FileBasicInformation);
    if (!NT_SUCCESS(NtStatus))
    {
        DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus);
    }
    else
    {
        FileBasic.FileAttributes = Attributes;

        NtStatus = NtSetInformationFile(hFile,
                                        &IoStatusBlock,
                                        &FileBasic,
                                        sizeof(FILE_BASIC_INFORMATION),
                                        FileBasicInformation);
        if (!NT_SUCCESS(NtStatus))
        {
            DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus);
        }
    }

    return NT_SUCCESS(NtStatus);
}
Пример #19
0
static int winfs_truncate(struct file *f, loff_t length)
{
    struct winfs_file *winfile = (struct winfs_file *) f;
    /* TODO: Correct errno */
    FILE_END_OF_FILE_INFORMATION info;
    info.EndOfFile.QuadPart = length;
    IO_STATUS_BLOCK status_block;
    NTSTATUS status;
    status = NtSetInformationFile(winfile->handle, &status_block, &info, sizeof(info), FileEndOfFileInformation);
    if (!NT_SUCCESS(status))
    {
        log_warning("NtSetInformationFile(FileEndOfFileInformation) failed, status: %x\n", status);
        return -EIO;
    }
    return 0;
}
Пример #20
0
static int winfs_rename(struct mount_point *mp, struct file *f, const char *newpath)
{
	AcquireSRWLockShared(&f->rw_lock);
	struct winfs_file *winfile = (struct winfs_file *)f;
	char buf[sizeof(FILE_RENAME_INFORMATION) + PATH_MAX * 2];
	NTSTATUS status;
	int r = 0;
	int retry_count = 5;
retry:
	if (--retry_count == 0)
	{
		r = -L_EPERM;
		goto out;
	}
	FILE_RENAME_INFORMATION *info = (FILE_RENAME_INFORMATION *)buf;
	info->ReplaceIfExists = TRUE;
	info->RootDirectory = NULL;
	info->FileNameLength = 2 * filename_to_nt_pathname(mp, newpath, info->FileName, PATH_MAX);
	if (info->FileNameLength == 0)
	{
		r = -L_ENOENT;
		goto out;
	}
	IO_STATUS_BLOCK status_block;
	status = NtSetInformationFile(winfile->handle, &status_block, info, info->FileNameLength + sizeof(FILE_RENAME_INFORMATION), FileRenameInformation);
	if (!NT_SUCCESS(status))
	{
		if (status == STATUS_ACCESS_DENIED)
		{
			/* The destination exists and the operation cannot be completed via a native operation.
			 * We remove the destination file first, then move this file again.
			 */
			r = winfs_unlink(mp, newpath);
			if (r)
				goto out;
			goto retry;
		}
		log_warning("NtSetInformationFile() failed, status: %x", status);
		r = -L_ENOENT;
		goto out;
	}
out:
	ReleaseSRWLockShared(&f->rw_lock);
	return r;
}
Пример #21
0
NTSTATUS NtSetFileAttributes(POBJECT_ATTRIBUTES ObjectAttributes, DWORD FileAttributes)
{
	HANDLE hFile;
	//OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(OBJECT_ATTRIBUTES), NULL, (UNICODE_STRING*)&FileName, OBJ_CASE_INSENSITIVE };
	IO_STATUS_BLOCK IoStatusBlock;

	auto Status = NtOpenFile(&hFile, FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, ObjectAttributes, &IoStatusBlock, FILE_SHARE_VALID_FLAGS, FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT);

	if (Status)
	{
		return Status;
	}
	FILE_BASIC_INFORMATION Info = { {},{},{},{}, FileAttributes };

	Status = NtSetInformationFile(hFile, &IoStatusBlock, &Info, sizeof(Info), FileBasicInformation);

	NtClose(hFile);

	return Status;
}
Пример #22
0
static int winfs_rename(struct file *f, const char *newpath)
{
    struct winfs_file *winfile = (struct winfs_file *)f;
    char buf[sizeof(FILE_RENAME_INFORMATION) + PATH_MAX * 2];
    NTSTATUS status;
    FILE_RENAME_INFORMATION *info = (FILE_RENAME_INFORMATION *)buf;
    info->ReplaceIfExists = TRUE; /* TODO: This should be worked on to provide true Linux semantics (refer to unlink()) */
    info->RootDirectory = NULL;
    info->FileNameLength = 2 * filename_to_nt_pathname(newpath, info->FileName, PATH_MAX);
    if (info->FileNameLength == 0)
        return -ENOENT;
    IO_STATUS_BLOCK status_block;
    status = NtSetInformationFile(winfile->handle, &status_block, info, info->FileNameLength + sizeof(FILE_RENAME_INFORMATION), FileRenameInformation);
    if (!NT_SUCCESS(status))
    {
        log_warning("NtSetInformationFile() failed, status: %x\n", status);
        return -ENOENT;
    }
    return 0;
}
Пример #23
0
static int winfs_link(struct file *f, const char *newpath)
{
    struct winfs_file *winfile = (struct winfs_file *) f;
    NTSTATUS status;
    char buf[sizeof(FILE_LINK_INFORMATION) + PATH_MAX * 2];
    FILE_LINK_INFORMATION *info = (FILE_LINK_INFORMATION *)buf;
    info->ReplaceIfExists = FALSE;
    info->RootDirectory = NULL;
    info->FileNameLength = 2 * filename_to_nt_pathname(newpath, info->FileName, PATH_MAX);
    if (info->FileNameLength == 0)
        return -ENOENT;
    IO_STATUS_BLOCK status_block;
    status = NtSetInformationFile(winfile->handle, &status_block, info, info->FileNameLength + sizeof(FILE_LINK_INFORMATION), FileLinkInformation);
    if (!NT_SUCCESS(status))
    {
        log_warning("NtSetInformationFile() failed, status: %x.\n", status);
        return -ENOENT;
    }
    return 0;
}
Пример #24
0
/*
 * @implemented
 */
BOOL
WINAPI
SetMailslotInfo(IN HANDLE hMailslot,
                IN DWORD lReadTimeout)
{
    FILE_MAILSLOT_SET_INFORMATION Buffer;
    LARGE_INTEGER Timeout;
    IO_STATUS_BLOCK Iosb;
    NTSTATUS Status;

    if (lReadTimeout == MAILSLOT_WAIT_FOREVER)
    {
        /* Set the max */
        Timeout.QuadPart = 0xFFFFFFFFFFFFFFFFLL;
    }
    else
    {
        /* Convert to NT format */
        Timeout.QuadPart = lReadTimeout * -10000LL;
    }

    Buffer.ReadTimeout = &Timeout;

    Status = NtSetInformationFile(hMailslot,
                                  &Iosb,
                                  &Buffer,
                                  sizeof(FILE_MAILSLOT_SET_INFORMATION),
                                  FileMailslotSetInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed (Status %x)!\n", Status);
        BaseSetLastNTError(Status);
        return FALSE;
     }

     return TRUE;
}
Пример #25
0
int XRenameFile(
	char *oldFilename,
	char *newFilename)
{
	ANSI_STRING             xboxFilename;
	IO_STATUS_BLOCK         ioStatusBlock;
	OBJECT_ATTRIBUTES       objectAttributes;
	FILE_RENAME_INFORMATION renameInfo;
	NTSTATUS                status;
	int                     handle;

#ifdef DEBUG
	debugPrint("XRenameFile oldFilename=%s newFilename=%s\n", oldFilename, newFilename);
#endif

	char tmp[200];
	int rc = XConvertDOSFilenameToXBOX(oldFilename, tmp);
	if (rc != STATUS_SUCCESS)
		return rc;
	RtlInitAnsiString(&xboxFilename, tmp);

	objectAttributes.RootDirectory = NULL;
	objectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
	objectAttributes.ObjectName = &xboxFilename;

	// Try to open the file
	// I'm not sure why we have to use these particular flags, but we do.
	status = NtCreateFile(
		(PHANDLE)handle,
		DELETE | SYNCHRONIZE,
		&objectAttributes,
		&ioStatusBlock,
		NULL,
		0,
		FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
		FILE_OPEN,
		FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_NON_DIRECTORY_FILE);

	if (!NT_SUCCESS(status))
		return RtlNtStatusToDosError(status);

	// Set up the rename information
	rc = XConvertDOSFilenameToXBOX(newFilename, tmp);
	if (rc != STATUS_SUCCESS)
		return rc;
	RtlInitAnsiString(&renameInfo.FileName, tmp);
	renameInfo.ReplaceIfExists = TRUE;
	renameInfo.RootDirectory = NULL;

	// Try to rename the file
	status = NtSetInformationFile(
		(HANDLE)handle, 
		&ioStatusBlock,
		&renameInfo,
		sizeof(renameInfo),
		FileRenameInformation);

	if (!NT_SUCCESS(status))
	{
		NtClose((HANDLE)handle);
		return RtlNtStatusToDosError(status);
	}
	else
	{
		NtClose((HANDLE)handle);
		return STATUS_SUCCESS;
	}
}
Пример #26
0
VOID Delete(
    IN PCHAR FileName
    )
{
    NTSTATUS Status;

    HANDLE FileHandle;
    OBJECT_ATTRIBUTES ObjectAttributes;
    STRING NameString;
    IO_STATUS_BLOCK IoStatus;

    //
    //  Get the filename
    //

    simprintf("Delete ", 0); simprintf(FileName, 0); simprintf("\n", 0);

    //
    //  Open the file for delete access
    //

    RtlInitString( &NameString, FileName );
    InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
    if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle,
                                           DELETE | SYNCHRONIZE,
                                           &ObjectAttributes,
                                           &IoStatus,
                                           (PLARGE_INTEGER)NULL,
                                           0L,
                                           0L,
                                           FILE_OPEN,
                                           WriteThrough,
                                           (PVOID)NULL,
                                           0L ))) {
        CreateFileError( Status, FileName );
        return;
    }

    //
    //  Mark the file for delete
    //

    ((PFILE_DISPOSITION_INFORMATION)&Buffer[0])->DeleteFile = TRUE;

    if (!NT_SUCCESS(Status = NtSetInformationFile( FileHandle,
                                                   &IoStatus,
                                                   Buffer,
                                                   sizeof(FILE_DISPOSITION_INFORMATION),
                                                   FileDispositionInformation))) {
        SetInformationFileError( Status );
        return;
    }

    //
    //  Now close the file
    //

    if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
        CloseError( Status );
    }

    //
    //  And return to our caller
    //

    return;
}
Пример #27
0
NTSTATUS
SetupCopyFile(
    PWCHAR SourceFileName,
    PWCHAR DestinationFileName)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE FileHandleSource;
    HANDLE FileHandleDest;
    static IO_STATUS_BLOCK IoStatusBlock;
    FILE_STANDARD_INFORMATION FileStandard;
    FILE_BASIC_INFORMATION FileBasic;
    ULONG RegionSize;
    UNICODE_STRING FileName;
    NTSTATUS Status;
    PVOID SourceFileMap = 0;
    HANDLE SourceFileSection;
    SIZE_T SourceSectionSize = 0;
    LARGE_INTEGER ByteOffset;

#ifdef __REACTOS__
    RtlInitUnicodeString(&FileName,
                         SourceFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtOpenFile(&FileHandleSource,
                        GENERIC_READ,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ,
                        FILE_SEQUENTIAL_ONLY);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName);
        goto done;
    }
#else
    FileHandleSource = CreateFileW(SourceFileName,
                                   GENERIC_READ,
                                   FILE_SHARE_READ,
                                   NULL,
                                   OPEN_EXISTING,
                                   0,
                                   NULL);
    if (FileHandleSource == INVALID_HANDLE_VALUE)
    {
        Status = STATUS_UNSUCCESSFUL;
        goto done;
    }
#endif

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,
                                    &FileStandard,
                                    sizeof(FILE_STANDARD_INFORMATION),
                                    FileStandardInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,&FileBasic,
                                    sizeof(FILE_BASIC_INFORMATION),
                                    FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtCreateSection(&SourceFileSection,
                             SECTION_MAP_READ,
                             NULL,
                             NULL,
                             PAGE_READONLY,
                             SEC_COMMIT,
                             FileHandleSource);
    if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName);
      goto closesrc;
    }

    Status = NtMapViewOfSection(SourceFileSection,
                                NtCurrentProcess(),
                                &SourceFileMap,
                                0,
                                0,
                                NULL,
                                &SourceSectionSize,
                                ViewUnmap,
                                0,
                                PAGE_READONLY );
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName);
        goto closesrcsec;
    }

    RtlInitUnicodeString(&FileName,
                         DestinationFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtCreateFile(&FileHandleDest,
                          GENERIC_WRITE | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          0,
                          FILE_OVERWRITE_IF,
                          FILE_NO_INTERMEDIATE_BUFFERING |
                          FILE_SEQUENTIAL_ONLY |
                          FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateFile failed: %x\n", Status);
        goto unmapsrcsec;
    }

    RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
    IoStatusBlock.Status = 0;
    ByteOffset.QuadPart = 0;
    Status = NtWriteFile(FileHandleDest,
                         NULL,
                         NULL,
                         NULL,
                         &IoStatusBlock,
                         SourceFileMap,
                         RegionSize,
                         &ByteOffset,
                         NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", Status, IoStatusBlock.Status, &IoStatusBlock, SourceFileMap, RegionSize);
        goto closedest;
    }

    /* Copy file date/time from source file */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileBasic,
                                  sizeof(FILE_BASIC_INFORMATION),
                                  FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
        goto closedest;
    }

    /* shorten the file back to it's real size after completing the write */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileStandard.EndOfFile,
                                  sizeof(FILE_END_OF_FILE_INFORMATION),
                                  FileEndOfFileInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
    }

closedest:
    NtClose(FileHandleDest);

unmapsrcsec:
    NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap);

closesrcsec:
    NtClose(SourceFileSection);

closesrc:
    NtClose(FileHandleSource);

done:
    return Status;
}
Пример #28
0
BOOL
APIENTRY
MoveFileExW(
    LPCWSTR lpExistingFileName,
    LPCWSTR lpNewFileName,
    DWORD dwFlags
    )

/*++

Routine Description:

    An existing file can be renamed using MoveFile.

Arguments:

    lpExistingFileName - Supplies the name of an existing file that is to be
        renamed.

    lpNewFileName - Supplies the new name for the existing file.  The new
        name must reside in the same file system/drive as the existing
        file and must not already exist.

    dwFlags - Supplies optional flag bits to control the behavior of the
        rename.  The following bits are currently defined:

        MOVEFILE_REPLACE_EXISTING - if the new file name exists, replace
            it by renaming the old file name on top of the new file name.

        MOVEFILE_COPY_ALLOWED - if the new file name is on a different
            volume than the old file name, and causes the rename operation
            to fail, then setting this flag allows the MoveFileEx API
            call to simulate the rename with a call to CopyFile followed
            by a call to DeleteFile to the delete the old file if the
            CopyFile was successful.

        MOVEFILE_DELAY_UNTIL_REBOOT - dont actually do the rename now, but
            instead queue the rename so that it will happen the next time
            the system boots.  If this flag is set, then the lpNewFileName
            parameter may be NULL, in which case a delay DeleteFile of
            the old file name will occur the next time the system is
            booted.

            The delay rename/delete operations occur immediately after
            AUTOCHK is run, but prior to creating any paging files, so
            it can be used to delete paging files from previous boots
            before they are reused.

        MOVEFILE_WRITE_THROUGH - perform the rename operation in such a
            way that the file has actually been moved on the disk before
            the API returns to the caller.  Note that this flag causes a
            flush at the end of a copy operation (if one were allowed and
            necessary), and has no effect if the rename operation is
            delayed until the next reboot.

Return Value:

    TRUE - The operation was successful.

    FALSE/NULL - The operation failed. Extended error status is available
        using GetLastError.

--*/

{
    NTSTATUS Status;
    BOOLEAN ReplaceIfExists;
    OBJECT_ATTRIBUTES Obja;
    HANDLE Handle;
    UNICODE_STRING OldFileName;
    UNICODE_STRING NewFileName;
    IO_STATUS_BLOCK IoStatusBlock;
    PFILE_RENAME_INFORMATION NewName;
    BOOLEAN TranslationStatus;
    RTL_RELATIVE_NAME RelativeName;
    PVOID FreeBuffer;
    ULONG OpenFlags;
    BOOLEAN fDoCrossVolumeMove;
    BOOLEAN b;

#ifdef _CAIRO_
    OBJECTID oid;
    OBJECTID *poid; // only can be valid when fDoCrossVolumeMove = TRUE
#else
    PVOID poid = NULL;
#endif

    //
    // if the target is a device, do not allow the rename !
    //
    if ( lpNewFileName ) {
        if ( RtlIsDosDeviceName_U((PWSTR)lpNewFileName) ) {
            SetLastError(ERROR_ALREADY_EXISTS);
            return FALSE;
        }
    }

    if (dwFlags & MOVEFILE_REPLACE_EXISTING) {
        ReplaceIfExists = TRUE;
    } else {
        ReplaceIfExists = FALSE;
    }

    TranslationStatus = RtlDosPathNameToNtPathName_U(
                            lpExistingFileName,
                            &OldFileName,
                            NULL,
                            &RelativeName
                            );

    if ( !TranslationStatus ) {
        SetLastError(ERROR_PATH_NOT_FOUND);
        return FALSE;
    }

    FreeBuffer = OldFileName.Buffer;

    if (!(dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT)) {

        if ( RelativeName.RelativeName.Length ) {
            OldFileName = *(PUNICODE_STRING)&RelativeName.RelativeName;
        } else {
            RelativeName.ContainingDirectory = NULL;
        }
        InitializeObjectAttributes(
            &Obja,
            &OldFileName,
            OBJ_CASE_INSENSITIVE,
            RelativeName.ContainingDirectory,
            NULL
            );

        //
        // Open the file for delete access
        //

        OpenFlags = FILE_SYNCHRONOUS_IO_NONALERT |
                    FILE_OPEN_FOR_BACKUP_INTENT |
                    (dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_WRITE_THROUGH : 0;

        Status = NtOpenFile(
                    &Handle,
#ifdef _CAIRO_
                    FILE_READ_ATTRIBUTES |
#endif
                    (ACCESS_MASK)DELETE | SYNCHRONIZE,
                    &Obja,
                    &IoStatusBlock,
                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                    OpenFlags
                    );

        if ( !NT_SUCCESS(Status) ) {
            RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);
            BaseSetLastNTError(Status);
            return FALSE;
        }
    }

    if (!(dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT) ||
        (lpNewFileName != NULL)) {
        TranslationStatus = RtlDosPathNameToNtPathName_U(
                                lpNewFileName,
                                &NewFileName,
                                NULL,
                                NULL
                                );

        if ( !TranslationStatus ) {
            RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);
            SetLastError(ERROR_PATH_NOT_FOUND);
            NtClose(Handle);
            return FALSE;
            }
    } else {
        RtlInitUnicodeString( &NewFileName, NULL );
    }

    if (dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT) {
        //
        // copy allowed is not permitted on delayed renames
        //


        //
        // (typical stevewo hack, preserved for sentimental value)
        //
        // If ReplaceIfExists is TRUE, prepend an exclamation point
        // to the new filename in order to pass this bit of data
        // along to the session manager.
        //
        if (ReplaceIfExists &&
            (NewFileName.Length != 0)) {
            PWSTR NewBuffer;

            NewBuffer = RtlAllocateHeap( RtlProcessHeap(),
                                         MAKE_TAG( TMP_TAG ),
                                         NewFileName.Length + sizeof(WCHAR) );
            if (NewBuffer != NULL) {
                NewBuffer[0] = L'!';
                CopyMemory(&NewBuffer[1], NewFileName.Buffer, NewFileName.Length);
                NewFileName.Length += sizeof(WCHAR);
                NewFileName.MaximumLength += sizeof(WCHAR);
                RtlFreeHeap(RtlProcessHeap(), 0, NewFileName.Buffer);
                NewFileName.Buffer = NewBuffer;
            }
        }

        if ( dwFlags & MOVEFILE_COPY_ALLOWED ) {
            Status = STATUS_INVALID_PARAMETER;
        } else {
            Status = BasepMoveFileDelayed(&OldFileName, &NewFileName);
        }
        RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);
        RtlFreeHeap(RtlProcessHeap(), 0, NewFileName.Buffer);

        if (NT_SUCCESS(Status)) {
            return(TRUE);
        } else {
            BaseSetLastNTError(Status);
            return(FALSE);
        }
    }

    RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);
    FreeBuffer = NewFileName.Buffer;

    NewName = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TMP_TAG ), NewFileName.Length+sizeof(*NewName));
    if (NewName != NULL) {
        RtlMoveMemory( NewName->FileName, NewFileName.Buffer, NewFileName.Length );

        NewName->ReplaceIfExists = ReplaceIfExists;
        NewName->RootDirectory = NULL;
        NewName->FileNameLength = NewFileName.Length;
        RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);

        Status = NtSetInformationFile(
                    Handle,
                    &IoStatusBlock,
                    NewName,
                    NewFileName.Length+sizeof(*NewName),
                    FileRenameInformation
                    );
        RtlFreeHeap(RtlProcessHeap(), 0, NewName);
    } else {
        Status = STATUS_NO_MEMORY;
    }

    fDoCrossVolumeMove = (Status == STATUS_NOT_SAME_DEVICE) &&
                         (dwFlags & MOVEFILE_COPY_ALLOWED);

#ifdef _CAIRO_
    if (fDoCrossVolumeMove)
    {
        // Get the object'd OBJECTID
        poid = RtlQueryObjectId(Handle, &oid) == STATUS_SUCCESS ? &oid : NULL;
    }
#endif

    NtClose(Handle);
    if ( NT_SUCCESS(Status) ) {
        return TRUE;
    } else if ( fDoCrossVolumeMove ) {
        HELPER_CONTEXT Context;

        Context.pObjectId = poid;
        Context.dwFlags = dwFlags;
        b = CopyFileExW(
                lpExistingFileName,
                lpNewFileName,
                poid || dwFlags & MOVEFILE_WRITE_THROUGH ? BasepCrossVolumeMoveHelper : NULL,
                &Context,
                NULL,
                ReplaceIfExists ? 0 : COPY_FILE_FAIL_IF_EXISTS
                );
        if ( b ) {

            //
            // the copy worked... Delete the source of the rename
            // if it fails, try a set attributes and then a delete
            //

            if (!DeleteFileW( lpExistingFileName ) ) {

                //
                // If the delete fails, we will return true, but possibly
                // leave the source dangling
                //

                SetFileAttributesW(lpExistingFileName,FILE_ATTRIBUTE_NORMAL);
                DeleteFileW( lpExistingFileName );

            }
            return TRUE;
        } else {
            return FALSE;
        }
    } else {
        BaseSetLastNTError(Status);
        return FALSE;
    }
}
Пример #29
0
BOOL
APIENTRY
SetFileAttributesW(
    LPCWSTR lpFileName,
    DWORD dwFileAttributes
    )

/*++

Routine Description:

    The attributes of a file can be set using SetFileAttributes.

    This API provides the same functionality as DOS (int 21h, function
    43H with AL=1), and provides a subset of OS/2's DosSetFileInfo.

Arguments:

    lpFileName - Supplies the file name of the file whose attributes are to
        be set.

    dwFileAttributes - Specifies the file attributes to be set for the
        file.  Any combination of flags is acceptable except that all
        other flags override the normal file attribute,
        FILE_ATTRIBUTE_NORMAL.

        FileAttributes Flags:

        FILE_ATTRIBUTE_NORMAL - A normal file should be created.

        FILE_ATTRIBUTE_READONLY - A read-only file should be created.

        FILE_ATTRIBUTE_HIDDEN - A hidden file should be created.

        FILE_ATTRIBUTE_SYSTEM - A system file should be created.

        FILE_ATTRIBUTE_ARCHIVE - The file should be marked so that it
            will be archived.

Return Value:

    TRUE - The operation was successful.

    FALSE/NULL - The operation failed. Extended error status is available
        using GetLastError.

--*/

{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES Obja;
    HANDLE Handle;
    UNICODE_STRING FileName;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_BASIC_INFORMATION BasicInfo;
    BOOLEAN TranslationStatus;
    RTL_RELATIVE_NAME RelativeName;
    PVOID FreeBuffer;

    TranslationStatus = RtlDosPathNameToNtPathName_U(
                            lpFileName,
                            &FileName,
                            NULL,
                            &RelativeName
                            );

    if ( !TranslationStatus ) {
        SetLastError(ERROR_PATH_NOT_FOUND);
        return FALSE;
        }

    FreeBuffer = FileName.Buffer;

    if ( RelativeName.RelativeName.Length ) {
        FileName = *(PUNICODE_STRING)&RelativeName.RelativeName;
        }
    else {
        RelativeName.ContainingDirectory = NULL;
        }

    InitializeObjectAttributes(
        &Obja,
        &FileName,
        OBJ_CASE_INSENSITIVE,
        RelativeName.ContainingDirectory,
        NULL
        );

    //
    // Open the file
    //

    Status = NtOpenFile(
                &Handle,
                (ACCESS_MASK)FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
                &Obja,
                &IoStatusBlock,
                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT
                );

    RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);
    if ( !NT_SUCCESS(Status) ) {
        BaseSetLastNTError(Status);
        return FALSE;
        }

    //
    // Set the attributes
    //

    RtlZeroMemory(&BasicInfo,sizeof(BasicInfo));
    BasicInfo.FileAttributes = (dwFileAttributes & FILE_ATTRIBUTE_VALID_SET_FLAGS) | FILE_ATTRIBUTE_NORMAL;

    Status = NtSetInformationFile(
                Handle,
                &IoStatusBlock,
                &BasicInfo,
                sizeof(BasicInfo),
                FileBasicInformation
                );

    NtClose(Handle);
    if ( NT_SUCCESS(Status) ) {
        return TRUE;
        }
    else {
        BaseSetLastNTError(Status);
        return FALSE;
        }
}
Пример #30
0
BOOL
APIENTRY
DeleteFileW(
    LPCWSTR lpFileName
    )

/*++

    Routine Description:

    An existing file can be deleted using DeleteFile.

    This API provides the same functionality as DOS (int 21h, function 41H)
    and OS/2's DosDelete.

Arguments:

    lpFileName - Supplies the file name of the file to be deleted.

Return Value:

    TRUE - The operation was successful.

    FALSE/NULL - The operation failed. Extended error status is available
        using GetLastError.

--*/

{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES Obja;
    HANDLE Handle;
    UNICODE_STRING FileName;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_DISPOSITION_INFORMATION Disposition;
    BOOLEAN TranslationStatus;
    RTL_RELATIVE_NAME RelativeName;
    PVOID FreeBuffer;

    TranslationStatus = RtlDosPathNameToNtPathName_U(
                            lpFileName,
                            &FileName,
                            NULL,
                            &RelativeName
                            );

    if ( !TranslationStatus ) {
        SetLastError(ERROR_PATH_NOT_FOUND);
        return FALSE;
        }

    FreeBuffer = FileName.Buffer;

    if ( RelativeName.RelativeName.Length ) {
        FileName = *(PUNICODE_STRING)&RelativeName.RelativeName;
        }
    else {
        RelativeName.ContainingDirectory = NULL;
        }

    InitializeObjectAttributes(
        &Obja,
        &FileName,
        OBJ_CASE_INSENSITIVE,
        RelativeName.ContainingDirectory,
        NULL
        );

    //
    // Open the file for delete access
    //

    Status = NtOpenFile(
                &Handle,
                (ACCESS_MASK)DELETE,
                &Obja,
                &IoStatusBlock,
                FILE_SHARE_DELETE |
                   FILE_SHARE_READ |
                   FILE_SHARE_WRITE,
                   FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT
                );
    RtlFreeHeap(RtlProcessHeap(), 0,FreeBuffer);
    if ( !NT_SUCCESS(Status) ) {
        BaseSetLastNTError(Status);
        return FALSE;
        }

    //
    // Delete the file
    //
#undef DeleteFile
    Disposition.DeleteFile = TRUE;

    Status = NtSetInformationFile(
                Handle,
                &IoStatusBlock,
                &Disposition,
                sizeof(Disposition),
                FileDispositionInformation
                );

    NtClose(Handle);
    if ( NT_SUCCESS(Status) ) {
        return TRUE;
        }
    else {
        BaseSetLastNTError(Status);
        return FALSE;
        }
}