Exemplo n.º 1
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;
}
Exemplo n.º 2
0
NTSTATUS
GetNextReparseVolumePath(
    IN  HANDLE          Handle,
    OUT PUNICODE_STRING Path
    )

/*++

Routine Description:

    This routine queries the reparse index for the next volume mount point.

Arguments:

    Handle  - Supplies the handle.

    Path    - Returns the path.


Return Value:

    NTSTATUS

--*/

{
    NTSTATUS                        status;
    IO_STATUS_BLOCK                 ioStatus;
    FILE_REPARSE_POINT_INFORMATION  reparseInfo;
    UNICODE_STRING                  fileId;
    OBJECT_ATTRIBUTES               oa;
    HANDLE                          h;
    PREPARSE_DATA_BUFFER            reparse;
    UNICODE_STRING                  volumeName;
    ULONG                           nameInfoSize;
    PFILE_NAME_INFORMATION          nameInfo;

    for (;;) {

        status = ZwQueryDirectoryFile(Handle, NULL, NULL, NULL, &ioStatus,
                                      &reparseInfo, sizeof(reparseInfo),
                                      FileReparsePointInformation, TRUE, NULL,
                                      FALSE);
        if (!NT_SUCCESS(status)) {
            return status;
        }

        if (reparseInfo.Tag != IO_REPARSE_TAG_MOUNT_POINT) {
            continue;
        }

        fileId.Length = sizeof(reparseInfo.FileReference);
        fileId.MaximumLength = fileId.Length;
        fileId.Buffer = (PWSTR) &reparseInfo.FileReference;

        InitializeObjectAttributes(&oa, &fileId, 0, Handle, NULL);

        status = ZwOpenFile(&h, SYNCHRONIZE | FILE_GENERIC_READ, &oa,
                            &ioStatus, FILE_SHARE_READ | FILE_SHARE_WRITE,
                            FILE_OPEN_BY_FILE_ID | FILE_OPEN_REPARSE_POINT |
                            FILE_SYNCHRONOUS_IO_ALERT);
        if (!NT_SUCCESS(status)) {
            continue;
        }

        reparse = ExAllocatePool(PagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
        if (!reparse) {
            ZwClose(h);
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        status = ZwFsControlFile(h, NULL, NULL, NULL, &ioStatus,
                                 FSCTL_GET_REPARSE_POINT, NULL, 0, reparse,
                                 MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
        if (!NT_SUCCESS(status)) {
            ExFreePool(reparse);
            ZwClose(h);
            continue;
        }

        volumeName.Length = reparse->MountPointReparseBuffer.SubstituteNameLength -
                            sizeof(WCHAR);
        volumeName.MaximumLength = volumeName.Length + sizeof(WCHAR);
        volumeName.Buffer = (PWCHAR)
                            ((PCHAR) reparse->MountPointReparseBuffer.PathBuffer +
                            reparse->MountPointReparseBuffer.SubstituteNameOffset);
        volumeName.Buffer[volumeName.Length/sizeof(WCHAR)] = 0;

        if (!IsVolumeName(&volumeName)) {
            ExFreePool(reparse);
            ZwClose(h);
            continue;
        }

        ExFreePool(reparse);

        nameInfoSize = 1024;
        nameInfo = ExAllocatePool(PagedPool, nameInfoSize);
        if (!nameInfo) {
            ZwClose(h);
            continue;
        }

        status = ZwQueryInformationFile(h, &ioStatus, nameInfo, nameInfoSize,
                                        FileNameInformation);
        ZwClose(h);
        if (!NT_SUCCESS(status)) {
            continue;
        }

        Path->Length = (USHORT) nameInfo->FileNameLength;
        Path->MaximumLength = Path->Length + sizeof(WCHAR);
        Path->Buffer = ExAllocatePool(PagedPool, Path->MaximumLength);
        if (!Path->Buffer) {
            ExFreePool(nameInfo);
            continue;
        }

        RtlCopyMemory(Path->Buffer, nameInfo->FileName, Path->Length);
        Path->Buffer[Path->Length/sizeof(WCHAR)] = 0;

        ExFreePool(nameInfo);
        break;
    }

    return status;
}
Exemplo n.º 3
0
/*++
 * @name RtlCliListDirectory
 *
 * The RtlCliListDirectory routine lists the current directory contents.
 *
 * @param None.
 *
 * @return NTSTATUS
 *
 * @remarks Documentation for this routine needs to be completed.
 *
 *--*/
NTSTATUS
RtlCliListDirectory(VOID)
{
    UNICODE_STRING DirectoryString;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE DirectoryHandle;
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatusBlock;
    BOOLEAN FirstQuery = TRUE;
    WCHAR CurrentDirectory[MAX_PATH];
    PFILE_BOTH_DIR_INFORMATION DirectoryInfo, Entry;
    HANDLE EventHandle;
    CHAR i, c;

    //
    // For now, we only support the current directory (ie: you can't dir e:\
    // without CDing into it first
    //
    RtlCliGetCurrentDirectory(CurrentDirectory);

    //
    // Convert it to NT Format
    //
    if (!RtlDosPathNameToNtPathName_U(CurrentDirectory,
                                      &DirectoryString,
                                      NULL,
                                      NULL))
    {
        //
        // Fail
        //
        return STATUS_UNSUCCESSFUL;
    }

    //
    // Initialize the object attributes
    //
    RtlCliDisplayString(" Directory of %S\n\n", CurrentDirectory);
    InitializeObjectAttributes(&ObjectAttributes,
                               &DirectoryString,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    //
    // Open the directory
    //
    Status = ZwCreateFile(&DirectoryHandle,
                          FILE_LIST_DIRECTORY,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          0,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          FILE_OPEN,
                          FILE_DIRECTORY_FILE,
                          NULL,
                          0);

    if (!NT_SUCCESS(Status)) 
    {
      return Status;
    }

    //
    // Allocate space for directory entry information
    //
    DirectoryInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, 4096);
    
    if (!DirectoryInfo) 
    {
      return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Create the event to wait on
    //
    InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
    Status = NtCreateEvent(&EventHandle,
                           EVENT_ALL_ACCESS,
                           &ObjectAttributes,
                           SynchronizationEvent,
                           FALSE);

    if (!NT_SUCCESS(Status)) 
    {
      return Status;
    }

    //
    // Start loop
    //
    i = 0;
    for (;;)
    {
        //
        // Get the contents of the directory, adding up the size as we go
        //
        Status = ZwQueryDirectoryFile(DirectoryHandle,
                                      EventHandle,
                                      NULL,
                                      0,
                                      &IoStatusBlock,
                                      DirectoryInfo,
                                      4096,
                                      FileBothDirectoryInformation,
                                      FALSE,
                                      NULL,
                                      FirstQuery);
        if (Status == STATUS_PENDING)
        {
            //
            // Wait on the event
            //
            NtWaitForSingleObject(EventHandle, FALSE, NULL);
            Status = IoStatusBlock.Status;
        }

        //
        // Check for success
        //
        if (!NT_SUCCESS(Status))
        {
            //
            // Nothing left to enumerate. Close handles and free memory
            //
            ZwClose(DirectoryHandle);
            RtlFreeHeap(RtlGetProcessHeap(), 0, DirectoryInfo);
            return STATUS_SUCCESS;
        }

        //
        // Loop every directory
        //
        Entry = DirectoryInfo;

        
        while(Entry)
        {            
            //
            // List the file
            //
            RtlCliDumpFileInfo(Entry);

            if (++i > 20)
            {
              i = 0;
              RtlCliDisplayString("Continue listing (Y/N):");         
              while (TRUE)
              {
                c = RtlCliGetChar(hKeyboard);
                if (c == 'n' || c == 'N')
                {
                  RtlCliDisplayString("\n");
                  return STATUS_SUCCESS;
                }
                if (c == 'y' || c == 'Y')
                {                  
                  break;
                }
              }     
              RtlCliDisplayString("\n");
            }

            //
            // Make sure we still have a file
            //
            if (!Entry->NextEntryOffset) break;

            //
            // Move to the next one
            //
            Entry = (PFILE_BOTH_DIR_INFORMATION)((ULONG_PTR)Entry +
                                                 Entry->NextEntryOffset);          
        }

        //
        // This isn't the first scan anymore
        //
        FirstQuery = FALSE;
    }
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
NTSTATUS NtCopyDirectory(OBJECT_ATTRIBUTES ExistingDirectoryPath, OBJECT_ATTRIBUTES NewDirectoryPath)
{
	HANDLE hExistingFile;
	//OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(OBJECT_ATTRIBUTES), hRootDir, (UNICODE_STRING*)&FileName, OBJ_CASE_INSENSITIVE };
	IO_STATUS_BLOCK IoStatusBlock;


	auto Status = NtOpenFile(&hExistingFile, SYNCHRONIZE | FILE_LIST_DIRECTORY| FILE_READ_ATTRIBUTES, &ExistingDirectoryPath, &IoStatusBlock, FILE_SHARE_VALID_FLAGS, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT);

	if (Status)
		return Status;

	HANDLE hNewFile;

	Status = NtCreateFile(&hNewFile, SYNCHRONIZE | FILE_LIST_DIRECTORY| FILE_WRITE_ATTRIBUTES, &NewDirectoryPath, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_VALID_FLAGS, FILE_OPEN_IF, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT, NULL, NULL);

	if (Status == 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 };
		NewDirectoryPath.RootDirectory = hNewFile;
		ExistingDirectoryPath.RootDirectory = hExistingFile;
		ExistingDirectoryPath.ObjectName = NewDirectoryPath.ObjectName = &TempFileName;


		byte FileBuffer[1024];

		FILE_BASIC_INFORMATION BaseInfo;
		while (ZwQueryDirectoryFile(hExistingFile, 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 (IsDots(FileInfo.FileName, FileInfo.FileNameLength))
					continue;

				Status = NtCopyDirectory(ExistingDirectoryPath, NewDirectoryPath);
			}
			else
			{
				HANDLE hExistingFile;

				Status = NtOpenFile(&hExistingFile, FILE_GENERIC_READ, &ExistingDirectoryPath, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT);

				if (Status)
					break;

				HANDLE hNewFile;

				Status = NtCreateFile(&hNewFile, SYNCHRONIZE | FILE_GENERIC_WRITE, &NewDirectoryPath, &IoStatusBlock, NULL, FileInfo.FileAttributes, FILE_SHARE_READ, FILE_OVERWRITE_IF, FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT, NULL, NULL);

				if (Status)
				{
					NtClose(hExistingFile);
					break;
				}

				DWORD cbData;

				while (true)
				{
					if (!ReadFile(hExistingFile, FileBuffer, sizeof(FileBuffer), &cbData, NULL))
					{
						Status = GetLastError_s();
						break;
					}

					if (!cbData)
						break;

					WriteFile(hNewFile, FileBuffer, cbData, &cbData, NULL);
				}

				if (NtQueryInformationFile(hExistingFile, &IoStatusBlock, &BaseInfo, sizeof(BaseInfo), FileBasicInformation)==0)
				{
					NtSetInformationFile(hNewFile,&IoStatusBlock, &BaseInfo, sizeof(BaseInfo), FileBasicInformation);
				}


				NtClose(hNewFile);
				NtClose(hExistingFile);
			}
		}

		if (NtQueryInformationFile(hExistingFile, &IoStatusBlock, &BaseInfo, sizeof(BaseInfo), FileBasicInformation) == 0)
		{
			NtSetInformationFile(hNewFile, &IoStatusBlock, &BaseInfo, sizeof(BaseInfo), FileBasicInformation);
		}

		NtClose(hNewFile);
	}

	NtClose(hExistingFile);

	return Status;
}
Exemplo n.º 7
0
co_rc_t co_os_file_getdir(char *dirname, co_filesystem_dir_names_t *names)
{
	UNICODE_STRING dirname_unicode;
	OBJECT_ATTRIBUTES attributes;
	NTSTATUS status;
	HANDLE handle;
	FILE_DIRECTORY_INFORMATION *dir_entries_buffer, *entry;
	unsigned long dir_entries_buffer_size = 0x1000;
	IO_STATUS_BLOCK io_status;
	BOOLEAN first_iteration = TRUE;
	co_filesystem_name_t *new_name;
	co_rc_t rc;

	co_list_init(&names->list);

	co_debug_lvl(filesystem, 10, "listing of '%s'", dirname);

	rc = co_winnt_utf8_to_unicode(dirname, &dirname_unicode);
	if (!CO_OK(rc))
		return rc;

	InitializeObjectAttributes(&attributes, &dirname_unicode,
				   OBJ_CASE_INSENSITIVE, NULL, NULL);

	status = ZwCreateFile(&handle, FILE_LIST_DIRECTORY,
			      &attributes, &io_status, NULL, 0, FILE_SHARE_DIRECTORY, 
			      FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, 
			      NULL, 0);
	
	if (!NT_SUCCESS(status)) {
		co_debug_lvl(filesystem, 5, "error %x ZwCreateFile('%s')", (int)status, dirname);
		rc = co_status_convert(status);
		goto error;
	}

	dir_entries_buffer = co_os_malloc(dir_entries_buffer_size);
	if (!dir_entries_buffer) {
		rc = CO_RC(OUT_OF_MEMORY);
		goto error_1;
	}

	for (;;) {
		status = ZwQueryDirectoryFile(handle, NULL, NULL, 0, &io_status, 
					      dir_entries_buffer, dir_entries_buffer_size, 
					      FileDirectoryInformation, FALSE, NULL, first_iteration);
		if (!NT_SUCCESS(status))
			break;

		entry = dir_entries_buffer;
  
		for (;;) {
			int filename_utf8_length;
			
			filename_utf8_length = co_utf8_wctowbstrlen(entry->FileName, entry->FileNameLength/sizeof(WCHAR));

			new_name = co_os_malloc(filename_utf8_length + sizeof(co_filesystem_name_t) + 2);
			if (!new_name) {
				rc = CO_RC(OUT_OF_MEMORY);
				goto error_2;
			}
			
			if (entry->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				new_name->type = FUSE_DT_DIR;
			else
				new_name->type = FUSE_DT_REG;

			rc = co_utf8_wcstombs(new_name->name, entry->FileName, filename_utf8_length + 1);
			if (!CO_OK(rc)) {
				co_os_free(new_name);
				goto error_2;
			}

			co_list_add_tail(&new_name->node, &names->list);
			if (entry->NextEntryOffset == 0)
				break;
			
			entry = (FILE_DIRECTORY_INFORMATION *)(((char *)entry) + entry->NextEntryOffset);
		}

		first_iteration = FALSE;
	}


	rc = CO_RC(OK);

error_2:
	if (!CO_OK(rc))
		co_filesystem_getdir_free(names);

	co_os_free(dir_entries_buffer);

error_1:
	ZwClose(handle);
error:
	co_winnt_free_unicode(&dirname_unicode);
	return rc;
}
Exemplo n.º 8
0
co_rc_t co_os_file_get_attr(char *fullname, struct fuse_attr *attr)
{
	char * dirname;
	char * filename;
	UNICODE_STRING dirname_unicode;
	UNICODE_STRING filename_unicode;
	OBJECT_ATTRIBUTES attributes;
	NTSTATUS status;
	HANDLE handle;
	struct {
		union {
			FILE_FULL_DIRECTORY_INFORMATION entry;
			FILE_BOTH_DIRECTORY_INFORMATION entry2;
		};
		WCHAR name_filler[sizeof(co_pathname_t)];
	} entry_buffer;
	IO_STATUS_BLOCK io_status;
	co_rc_t rc;
	int len, len1;
	LARGE_INTEGER LastAccessTime;
	LARGE_INTEGER LastWriteTime;
	LARGE_INTEGER ChangeTime;
	LARGE_INTEGER EndOfFile;
	ULONG FileAttributes;

	attr->uid = 0;
	attr->gid = 0;
	attr->rdev = 0;
	attr->_dummy = 0;
	attr->nlink = 1;

	len = co_strlen(fullname);
	len1 = len;

	/* Hack: WinNT detects "C:\" not as directory! */
	if (len >= 3 && fullname[len-1] == ':') {
		co_debug_lvl(filesystem, 10, "Root dir: '%s'", fullname);

		attr->atime = \
		attr->mtime = \
		attr->ctime = co_os_get_time();

		attr->mode = FUSE_S_IFDIR | 0777;

		attr->size = 0;
		attr->blocks = 0;

		return CO_RC(OK);
	}

	while (len > 0 && fullname[len-1] != '\\') {
		if (fullname[len-1] == '?' || fullname[len-1] == '*') {
			co_debug_lvl(filesystem, 5, "error: Wildcard in filename ('%s')", fullname);
			return CO_RC(NOT_FOUND);
		}
		len--;
	}

	dirname = co_os_malloc(len+1);
	if (!dirname) {
		co_debug_lvl(filesystem, 5, "no memory");
		return CO_RC(OUT_OF_MEMORY);
	}

	memcpy(dirname, fullname, len);
	dirname[len] = 0;

	filename = &fullname[len];

	rc = co_winnt_utf8_to_unicode(dirname, &dirname_unicode);
	if (!CO_OK(rc))
		goto error_0;

	rc = co_winnt_utf8_to_unicode(filename, &filename_unicode);
	if (!CO_OK(rc))
		goto error_1;

	InitializeObjectAttributes(&attributes, &dirname_unicode,
				   OBJ_CASE_INSENSITIVE, NULL, NULL);

	status = ZwCreateFile(&handle, FILE_LIST_DIRECTORY,
			      &attributes, &io_status, NULL, 0, FILE_SHARE_DIRECTORY,
			      FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE,
			      NULL, 0);

	if (!NT_SUCCESS(status)) {
		co_debug_lvl(filesystem, 5, "error %x ZwCreateFile('%s')", (int)status, dirname);
		rc = co_status_convert(status);
		goto error_2;
	}

	status = ZwQueryDirectoryFile(handle, NULL, NULL, 0, &io_status,
				      &entry_buffer, sizeof(entry_buffer),
				      FileFullDirectoryInformation, PTRUE, &filename_unicode,
				      PTRUE);
	if (!NT_SUCCESS(status)) {
		if (status == STATUS_UNMAPPABLE_CHARACTER) {
			status = ZwQueryDirectoryFile(handle, NULL, NULL, 0, &io_status,
						      &entry_buffer, sizeof(entry_buffer),
						      FileBothDirectoryInformation, PTRUE, &filename_unicode,
						      PTRUE);
			
			if (!NT_SUCCESS(status)) {
				co_debug_lvl(filesystem, 5, "error %x ZwQueryDirectoryFile('%s')", (int)status, filename);
				rc = co_status_convert(status);
				goto error_3;
			} else {
				LastAccessTime = entry_buffer.entry2.LastAccessTime;
				LastWriteTime = entry_buffer.entry2.LastWriteTime;
				ChangeTime = entry_buffer.entry2.ChangeTime;
				EndOfFile = entry_buffer.entry2.EndOfFile;
				FileAttributes = entry_buffer.entry2.FileAttributes;
			}
		} else {
			co_debug_lvl(filesystem, 5, "error %x ZwQueryDirectoryFile('%s')", (int)status, filename);
			rc = co_status_convert(status);
			goto error_3;
		}
	} else {
		LastAccessTime = entry_buffer.entry.LastAccessTime;
		LastWriteTime = entry_buffer.entry.LastWriteTime;
		ChangeTime = entry_buffer.entry.ChangeTime;
		EndOfFile = entry_buffer.entry.EndOfFile;
		FileAttributes = entry_buffer.entry.FileAttributes;
	}

	attr->atime = windows_time_to_unix_time(LastAccessTime);
	attr->mtime = windows_time_to_unix_time(LastWriteTime);
	attr->ctime = windows_time_to_unix_time(ChangeTime);

	#define FUSE_S_IR (FUSE_S_IRUSR | FUSE_S_IRGRP | FUSE_S_IROTH)
	#define FUSE_S_IW (FUSE_S_IWUSR | FUSE_S_IWGRP | FUSE_S_IWOTH)
	#define FUSE_S_IX (FUSE_S_IXUSR | FUSE_S_IXGRP | FUSE_S_IXOTH)

	if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		attr->mode = FUSE_S_IFDIR
			   | ((FileAttributes & FILE_ATTRIBUTE_HIDDEN)   ? 0 : FUSE_S_IR)
			   | ((FileAttributes & FILE_ATTRIBUTE_READONLY) ? 0 : FUSE_S_IW)
			   | ((FileAttributes & FILE_ATTRIBUTE_SYSTEM)   ? 0 : FUSE_S_IX);
	else
		attr->mode = FUSE_S_IFREG
			   | ((FileAttributes & FILE_ATTRIBUTE_HIDDEN)   ? 0 : FUSE_S_IR)
			   | ((FileAttributes & FILE_ATTRIBUTE_READONLY) ? 0 : FUSE_S_IW)
			   | ((FileAttributes & FILE_ATTRIBUTE_SYSTEM)   ? FUSE_S_IX : 0);

	attr->size = EndOfFile.QuadPart;
	attr->blocks = (EndOfFile.QuadPart + ((1<<10)-1)) >> 10;

	rc = CO_RC(OK);

error_3:
	ZwClose(handle);
error_2:
	co_winnt_free_unicode(&filename_unicode);
error_1:
	co_winnt_free_unicode(&dirname_unicode);
error_0:
	co_os_free(dirname);
	return rc;
}
Exemplo n.º 9
0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Searches for files according to specified Mask starting from specified Path. Links all found into the FileListHead.
//	Returns number of files found.
//
ULONG	FilesFind(
		  PWCHAR			Directory,		// directory name to search in
		  PWCHAR			Mask,			// search mask
  		  ULONG				Flags,			// variouse flags		
		  PLIST_ENTRY		FileListHead	// result list of file descriptors
		  )
{
	ULONG	bSize, Found = 0;
	HANDLE	hDir;
	NTSTATUS	ntStatus;
	UNICODE_STRING		uDirectory;
	OBJECT_ATTRIBUTES	oa = {0};
	IO_STATUS_BLOCK		IoStatus = {0};
	PFILE_DIRECTORY_INFORMATION	FileInfo, CurInfo;
	PFILE_DIRECTORY_ENTRY		DirEntry;
	ULONG	DirLenBytes = wcslen(Directory) * sizeof(WCHAR);

	RtlInitUnicodeString(&uDirectory, Directory);
	InitializeObjectAttributes(&oa, &uDirectory, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, NULL);

	ntStatus = ZwCreateFile(&hDir, GENERIC_READ, &oa, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, 
		FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

	if (NT_SUCCESS(ntStatus))
	{
		if (FileInfo = MyAllocatePool(PagedPool, PAGE_SIZE))
		{
			do
			{
				ntStatus = ZwQueryDirectoryFile(hDir, NULL, NULL, 0, &IoStatus, FileInfo, PAGE_SIZE - sizeof(WCHAR), FileDirectoryInformation, FALSE, NULL, FALSE);
				if (NT_SUCCESS(ntStatus))
				{
					CurInfo = FileInfo;
					do 
					{
						if (CurInfo->FileName[0] != '.')
						{
							if (!(CurInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (Flags & FILES_FIND_DIRECTORIES))
							{
								ULONG	NameLen = CurInfo->FileNameLength >> 1;
								WCHAR	z = CurInfo->FileName[NameLen];
								CurInfo->FileName[NameLen] = 0;

								if (__wcswicmp(Mask, (PWCHAR)&CurInfo->FileName))
								{
									if (DirEntry = FilesAlocateDirEntry(DirLenBytes + CurInfo->FileNameLength))
									{
										RtlCopyMemory(&DirEntry->FileInfo, CurInfo, sizeof(FILE_DIRECTORY_INFORMATION));
										RtlCopyMemory(&DirEntry->FileInfo.FileName, Directory, DirLenBytes);
										RtlCopyMemory(&DirEntry->FileInfo.FileName[DirLenBytes >> 1], &CurInfo->FileName, CurInfo->FileNameLength);
										InsertTailList(FileListHead, &DirEntry->Entry);
										Found += 1;
									}
								}	// if (__wcswicmp(Mask, (PWCHAR)&CurInfo->FileName))
								CurInfo->FileName[NameLen] = z;
							}	// if (!(CurInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (Flags & FILES_FIND_DIRECTORIES))

							if ((CurInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (Flags & FILES_SCAN_SUBDIRECTORIES))
							{
								PWCHAR	NewDir = MyAllocatePool(PagedPool, DirLenBytes + CurInfo->FileNameLength + 2*sizeof(WCHAR));
								if (NewDir)
								{
									RtlCopyMemory(NewDir, Directory, DirLenBytes);
									RtlCopyMemory((PCHAR)NewDir + DirLenBytes, CurInfo->FileName, CurInfo->FileNameLength);
									NewDir[(DirLenBytes + CurInfo->FileNameLength) >> 1] = '\\';
									NewDir[(DirLenBytes + CurInfo->FileNameLength + sizeof(WCHAR)) >> 1] = 0;
									Found += FilesFind(NewDir, Mask, Flags, FileListHead);
									MyFreePool(NewDir);
								}
							}	// if ((CurInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (Flags & FILES_SCAN_SUBDIRECTORIES))
						}	// if (CurInfo->FileName[0] != '.')

						if (CurInfo->NextEntryOffset == 0)
							break;
						CurInfo = (PFILE_DIRECTORY_INFORMATION)((PCHAR)CurInfo + CurInfo->NextEntryOffset);
					} while(TRUE);
				}	// if (NT_SUCCESS(ntStatus))
			} while(NT_SUCCESS(ntStatus));			
Exemplo n.º 10
-2
EXTERN_C NTSTATUS EnumDirectory( char *lpDirName )
{
	NTSTATUS status, fStatus; 
	ULONG dwBytesReturned; 
	OBJECT_ATTRIBUTES objectAttributes; 
	PDEVICE_OBJECT lpDeviceObject;
	IO_STACK_LOCATION iost; 
	PIO_STACK_LOCATION lpsp; 
	IO_STATUS_BLOCK IoStatus; 
	HANDLE hFile = NULL;
	PFILE_DIRECTORY_INFORMATION lpInformation; 
	PDIRECTORY_INFO lpDirInfo = NULL, lpPreDirInfo = NULL; 
	PFILE_OBJECT lpFileObject = NULL;
	UNICODE_STRING unFileName;
	ANSI_STRING anFileName;
	HANDLE  eventHandle = NULL;
	CHAR buffer[1024]; 
	PUCHAR lpNext;

	dwBytesReturned = 0; 
	status = STATUS_UNSUCCESSFUL; 
	RtlZeroMemory(buffer,1024); 
	strcpy(buffer,"\\DosDevices\\"); 
	strcat(buffer,lpDirName); 
	RtlInitAnsiString(&anFileName,buffer); 
	RtlAnsiStringToUnicodeString(&unFileName,&anFileName,TRUE); 
	InitializeObjectAttributes(&objectAttributes,&unFileName,OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,NULL,NULL);

	__try
	{
		//打开文件
		fStatus = ZwOpenFile(&hFile,\
			FILE_LIST_DIRECTORY | SYNCHRONIZE | FILE_ANY_ACCESS,\
			&objectAttributes,\
			&IoStatus,\
			FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);

		ObReferenceObjectByHandle(hFile, FILE_LIST_DIRECTORY | SYNCHRONIZE, 0, KernelMode, (PVOID *)&lpFileObject, NULL); 

		status = ZwCreateEvent(&eventHandle, GENERIC_ALL, 0, NotificationEvent,
			FALSE);

		lpInformation = (PFILE_DIRECTORY_INFORMATION)ExAllocatePool(PagedPool, 655350); 
		status = ZwQueryDirectoryFile(hFile, eventHandle,0, 0, &IoStatus,
			lpInformation, 655350,
			FileDirectoryInformation, FALSE, NULL,
			FALSE );

		if (!NT_SUCCESS(status) && status != STATUS_PENDING)
		{
			goto LeaveBefore;
		}
		if (status == STATUS_PENDING)
		{
			KeWaitForSingleObject(eventHandle, Executive, KernelMode, TRUE, 0);
		}

		FreePagedLookasideListForDirectory();
		g_pPageListDirectory = (PPAGED_LOOKASIDE_LIST)ExAllocatePool(PagedPool, sizeof(PAGED_LOOKASIDE_LIST));
		ExInitializePagedLookasideList(g_pPageListDirectory, NULL, NULL, 0, sizeof(DIRECTORY_INFO), NULL, 0);

		while(1) 
		{
			lpDirInfo = (PDIRECTORY_INFO)ExAllocateFromPagedLookasideList(g_pPageListDirectory);
			RtlZeroMemory(lpDirInfo, sizeof(DIRECTORY_INFO));

			RtlCopyMemory(lpDirInfo->FileName, lpInformation->FileName, lpInformation->FileNameLength);
			lpDirInfo->AllocationSize = lpInformation->AllocationSize;
			lpDirInfo->FileAttributes = lpInformation->FileAttributes;
			RtlTimeToTimeFields(&(lpInformation->CreationTime), &(lpDirInfo->CreationTime)); 
			RtlTimeToTimeFields(&(lpInformation->LastAccessTime), &(lpDirInfo->LastAccessTime));  
			RtlTimeToTimeFields(&(lpInformation->LastWriteTime), &(lpDirInfo->LastWriteTime));  
			RtlTimeToTimeFields(&(lpInformation->ChangeTime), &(lpDirInfo->ChangeTime));
			lpDirInfo->next = NULL;

			if (NULL == g_pDirectoryInfo)
			{
				g_pDirectoryInfo = lpDirInfo;
				lpPreDirInfo = lpDirInfo;
			}
			else
			{
				lpPreDirInfo->next = lpDirInfo;
				lpPreDirInfo = lpDirInfo;
			}

			if(!lpInformation->NextEntryOffset)
			{
				break;
			}

			lpInformation = (PFILE_DIRECTORY_INFORMATION)((PUCHAR)lpInformation + lpInformation->NextEntryOffset);

		} 
LeaveBefore:
		;
	}
	__finally
	{
		if (NT_SUCCESS(fStatus))
		{
			ZwClose(hFile);
		}
		if (NULL != lpFileObject)
		{
			ObDereferenceObject(lpFileObject);
			lpFileObject = NULL;
		}
		if (NULL != eventHandle)
		{
			ZwClose(eventHandle);
			eventHandle = NULL;
		}

	}

	return status;               
}