Ejemplo n.º 1
0
/* Returns whether the path refers to a link-like object, e.g. a junction
 * point, symbolic link, or mounted folder. */
static int is_name_surrogate(const efile_path_t *path) {
    HANDLE handle;
    int result;

    handle = CreateFileW((const WCHAR*)path->data, GENERIC_READ,
                         FILE_SHARE_FLAGS, NULL, OPEN_EXISTING,
                         FILE_FLAG_OPEN_REPARSE_POINT |
                         FILE_FLAG_BACKUP_SEMANTICS,
                         NULL);
    result = 0;

    if(handle != INVALID_HANDLE_VALUE) {
        REPARSE_GUID_DATA_BUFFER reparse_buffer;
        DWORD unused_length;
        BOOL success;

        success = DeviceIoControl(handle,
                                  FSCTL_GET_REPARSE_POINT, NULL, 0,
                                  &reparse_buffer, sizeof(reparse_buffer),
                                  &unused_length, NULL);

        /* ERROR_MORE_DATA is tolerated since we're guaranteed to have filled
         * the field we want. */
        if(success || GetLastError() == ERROR_MORE_DATA) {
            result = IsReparseTagNameSurrogate(reparse_buffer.ReparseTag);
        }

        CloseHandle(handle);
     }

     return result;
}
Ejemplo n.º 2
0
UINT64 GetDirectorySizeInternal(OBJECT_ATTRIBUTES ObjectAttributes)
{
	HANDLE hFile;
	//OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(OBJECT_ATTRIBUTES), hRootDir, (UNICODE_STRING*)&FileName, OBJ_CASE_INSENSITIVE };
	IO_STATUS_BLOCK IoStatusBlock;


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

	if (Status)
		return 0;

	UINT64 Space = 0;

	byte Buffer[sizeof(FILE_FULL_DIR_INFORMATION) + 512];


	FILE_FULL_DIR_INFORMATION & FileInfo = *(FILE_FULL_DIR_INFORMATION *)Buffer;

	UNICODE_STRING TempFileName = { 0,0,FileInfo.FileName };

	ObjectAttributes.RootDirectory = hFile;
	ObjectAttributes.ObjectName = &TempFileName;

	while (ZwQueryDirectoryFile(hFile, NULL, NULL, NULL, &IoStatusBlock, Buffer, sizeof(Buffer), FileFullDirectoryInformation, -1, NULL, 0) == ERROR_SUCCESS)
	{
		if (FileInfo.FileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		{
			if (FileInfo.FileAttributes&FILE_ATTRIBUTE_REPARSE_POINT)
			{
				if (IsReparseTagNameSurrogate(FileInfo.EaSize))
					continue;
			}
			else
			{
				if (IsDots(FileInfo.FileName, FileInfo.FileNameLength))
					continue;
			}

			TempFileName.Length = TempFileName.MaximumLength = FileInfo.FileNameLength;

			Space += GetDirectorySizeInternal(ObjectAttributes);
		}
		else
		{
			Space += FileInfo.AllocationSize.QuadPart;
		}
	}

	NtClose(hFile);

	return Space;
}
Ejemplo n.º 3
0
UINT64 GetDirectoryAllocationSizeInternal(OBJECT_ATTRIBUTES ObjectAttributes, std::map<UINT64, DWORD>& FileMap)
{
	HANDLE hFile;
	//OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(OBJECT_ATTRIBUTES), hRootDir, (UNICODE_STRING*)&FileName, OBJ_CASE_INSENSITIVE };
	IO_STATUS_BLOCK IoStatusBlock;


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

	if (Status)
		return 0;

	UINT64 Space = 0;

	byte Buffer[sizeof(FILE_FULL_DIR_INFORMATION) + 512];


	FILE_FULL_DIR_INFORMATION & FileInfo = *(FILE_FULL_DIR_INFORMATION *)Buffer;

	UNICODE_STRING TempFileName = { 0,0,FileInfo.FileName };
	Status = -1;
	ObjectAttributes.RootDirectory = hFile;
	ObjectAttributes.ObjectName = &TempFileName;

	FILE_STANDARD_INFORMATION FileStandardInfo;
	FILE_INTERNAL_INFORMATION FileInternalInfo;

	while (ZwQueryDirectoryFile(hFile, NULL, NULL, NULL, &IoStatusBlock, Buffer, sizeof(Buffer), FileFullDirectoryInformation, -1, NULL, 0) == ERROR_SUCCESS)
	{
		TempFileName.Length = TempFileName.MaximumLength = FileInfo.FileNameLength;

		if (FileInfo.FileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		{
			if (FileInfo.FileAttributes&FILE_ATTRIBUTE_REPARSE_POINT)
			{
				if (IsReparseTagNameSurrogate(FileInfo.EaSize))
					continue;
			}
			else
			{
				if (IsDots(FileInfo.FileName, FileInfo.FileNameLength))
					continue;
			}

			Space += GetDirectoryAllocationSizeInternal(ObjectAttributes, FileMap);
		}
		else
		{
			if (NtGetFileId(&ObjectAttributes, &FileStandardInfo, &FileInternalInfo))
				continue;

			if (FileStandardInfo.NumberOfLinks != 1)
			{
				auto T = FileMap.insert(std::pair<UINT64, DWORD>(FileInternalInfo.IndexNumber.QuadPart, FileStandardInfo.NumberOfLinks)).first;

				if (--(T->second))
					continue;
			}

			Space += FileInfo.AllocationSize.QuadPart;
		}
	}

	NtClose(hFile);

	return Space;
}
Ejemplo n.º 4
0
NTSTATUS DeleteDirectoryInternal(OBJECT_ATTRIBUTES ObjectAttributes)
{
	HANDLE hFile;
	//OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(OBJECT_ATTRIBUTES), hRootDir, (UNICODE_STRING*)&FileName, OBJ_CASE_INSENSITIVE };
	IO_STATUS_BLOCK IoStatusBlock;


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

	if (Status)
		return Status;

	byte Buffer[sizeof(FILE_FULL_DIR_INFORMATION) + 512];


	FILE_FULL_DIR_INFORMATION & FileInfo = *(FILE_FULL_DIR_INFORMATION *)Buffer;

	UNICODE_STRING TempFileName = { 0,0,FileInfo.FileName };

	ObjectAttributes.RootDirectory = hFile;
	ObjectAttributes.ObjectName = &TempFileName;

	NTSTATUS Error = 0;

	while (ZwQueryDirectoryFile(hFile, NULL, NULL, NULL, &IoStatusBlock, Buffer, sizeof(Buffer), FileFullDirectoryInformation, -1, NULL, 0) == ERROR_SUCCESS)
	{
		TempFileName.Length = TempFileName.MaximumLength = FileInfo.FileNameLength;

		if (FileInfo.FileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		{
			if ((FileInfo.FileAttributes&FILE_ATTRIBUTE_REPARSE_POINT))
			{
				if (IsReparseTagNameSurrogate(FileInfo.EaSize))
					goto StartDelete;
			}
			else
			{
				if (IsDots(FileInfo.FileName, FileInfo.FileNameLength))
					continue;
			}

			if (Error = DeleteDirectoryInternal(ObjectAttributes))
			{
				goto OnError;
			}
		}

	StartDelete:

		if (FileInfo.FileAttributes&FILE_ATTRIBUTE_READONLY)
		{
			//取消只读属性
			if (Error = NtSetFileAttributes(&ObjectAttributes, FileInfo.FileAttributes^FILE_ATTRIBUTE_READONLY))
			{
				goto OnError;
			}
		}

		if (Error = NtDeleteFile2(&ObjectAttributes))
		{
			if (FileInfo.FileAttributes&FILE_ATTRIBUTE_READONLY)
			{
				//删除失败恢复只读属性
				NtSetFileAttributes(&ObjectAttributes, FileInfo.FileAttributes);
			}

		OnError:
			Status = Error;
		}
	}
//End:

	NtClose(hFile);

	return Status;
}
Ejemplo n.º 5
0
NTSTATUS DeleteFile2(LPCWSTR FilePath)
{
	UNICODE_STRING usFileName;

	if (!RtlDosPathNameToNtPathName_U(FilePath, &usFileName, NULL, NULL))
	{
		return RtlGetLastNtStatus();
	}

	OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(OBJECT_ATTRIBUTES), NULL, &usFileName, OBJ_CASE_INSENSITIVE };

	HANDLE hFile;

	IO_STATUS_BLOCK IoStatusBlock;

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

	if (Status)
	{
		goto Error2;
	}

	FILE_ATTRIBUTE_TAG_INFORMATION FileAttributeTagInfo;

	Status = NtQueryInformationFile(hFile, &IoStatusBlock, &FileAttributeTagInfo, sizeof(FileAttributeTagInfo), FileAttributeTagInformation);

	NtClose(hFile);

	if (Status)
	{
		goto Error2;
	}

	if (FileAttributeTagInfo.FileAttributes&FILE_ATTRIBUTE_READONLY)
	{
		if (Status = NtSetFileAttributes(&ObjectAttributes, FileAttributeTagInfo.FileAttributes^FILE_ATTRIBUTE_READONLY))
			goto Error2;
	}

	if (FileAttributeTagInfo.FileAttributes&FILE_ATTRIBUTE_REPARSE_POINT)
	{
		if (IsReparseTagNameSurrogate(FileAttributeTagInfo.ReparseTag))
			goto Delete;
	}

	if (FileAttributeTagInfo.FileAttributes&FILE_ATTRIBUTE_DIRECTORY)
	{
		if (Status = DeleteDirectoryInternal(ObjectAttributes))
			goto Error;
	}

Delete:
	Status = NtDeleteFile2(&ObjectAttributes);

Error:
	if (FileAttributeTagInfo.FileAttributes&FILE_ATTRIBUTE_REPARSE_POINT)
	{
		NtSetFileAttributes(&ObjectAttributes, FileAttributeTagInfo.FileAttributes);
	}

Error2:


	RtlFreeUnicodeString(&usFileName);

	return Status;
}