Example #1
0
NTSTATUS
DokanSetDispositionInformation(
	 PEVENT_CONTEXT		EventContext,
	 PDOKAN_FILE_INFO	FileInfo,
	 PDOKAN_OPERATIONS	DokanOperations)
{
	PFILE_DISPOSITION_INFORMATION dispositionInfo =
		(PFILE_DISPOSITION_INFORMATION)((PCHAR)EventContext + EventContext->Operation.SetFile.BufferOffset);

	if (!DokanOperations->DeleteFile || !DokanOperations->DeleteDirectory)
		return STATUS_NOT_IMPLEMENTED;

	if (!dispositionInfo->DeleteFile) {
		return STATUS_SUCCESS;
	}

	if (FileInfo->IsDirectory) {
		return DokanOperations->DeleteDirectory(
			EventContext->Operation.SetFile.FileName,
			FileInfo);
	} else {
		return DokanOperations->DeleteFile(
			EventContext->Operation.SetFile.FileName,
			FileInfo);
	}
}
Example #2
0
NTSTATUS
DokanSetAllocationInformation(
	 PEVENT_CONTEXT		EventContext,
	 PDOKAN_FILE_INFO	FileInfo,
	 PDOKAN_OPERATIONS	DokanOperations)
{
	PFILE_ALLOCATION_INFORMATION allocInfo =
		(PFILE_ALLOCATION_INFORMATION)((PCHAR)EventContext + EventContext->Operation.SetFile.BufferOffset);

	// A file's allocation size and end-of-file position are independent of each other,
	// with the following exception: The end-of-file position must always be less than
	// or equal to the allocation size. If the allocation size is set to a value that
	// is less than the end-of-file position, the end-of-file position is automatically
	// adjusted to match the allocation size.

	if (DokanOperations->SetAllocationSize) {
		return DokanOperations->SetAllocationSize(
			EventContext->Operation.SetFile.FileName,
			allocInfo->AllocationSize.QuadPart,
			FileInfo);
	}
	// How can we check the current end-of-file position?
	if (allocInfo->AllocationSize.QuadPart == 0) {
		return DokanOperations->SetEndOfFile(
			EventContext->Operation.SetFile.FileName,
			allocInfo->AllocationSize.QuadPart,
			FileInfo);
	} else {
		DbgPrint("  SetAllocationInformation %I64d, can't handle this parameter.\n",
				allocInfo->AllocationSize.QuadPart);
	}

	return STATUS_SUCCESS;
}
Example #3
0
NTSTATUS
DokanSetRenameInformation(
PEVENT_CONTEXT		EventContext,
	 PDOKAN_FILE_INFO	FileInfo,
	 PDOKAN_OPERATIONS	DokanOperations)
{
	PDOKAN_RENAME_INFORMATION renameInfo =
		(PDOKAN_RENAME_INFORMATION)((PCHAR)EventContext + EventContext->Operation.SetFile.BufferOffset);

	WCHAR newName[MAX_PATH];
	ZeroMemory(newName, sizeof(newName));

	if (renameInfo->FileName[0] != L'\\') {
		ULONG pos;
		for (pos = EventContext->Operation.SetFile.FileNameLength / sizeof(WCHAR);
			pos != 0; --pos) {
			if (EventContext->Operation.SetFile.FileName[pos] == '\\')
				break;
		}
		RtlCopyMemory(newName, EventContext->Operation.SetFile.FileName, (pos + 1)*sizeof(WCHAR));
		RtlCopyMemory((PCHAR)newName + (pos+1)*sizeof(WCHAR), renameInfo->FileName, renameInfo->FileNameLength);
	} else {
		RtlCopyMemory(newName, renameInfo->FileName, renameInfo->FileNameLength);
	}

	if (!DokanOperations->MoveFile)
		return STATUS_NOT_IMPLEMENTED;

	return DokanOperations->MoveFile(
		EventContext->Operation.SetFile.FileName,
		newName,
		renameInfo->ReplaceIfExists,
		FileInfo);
}
Example #4
0
NTSTATUS
DokanFsFullSizeInformation(PEVENT_INFORMATION EventInfo,
                           PEVENT_CONTEXT EventContext,
                           PDOKAN_FILE_INFO FileInfo,
                           PDOKAN_OPERATIONS DokanOperations) {
  ULONGLONG freeBytesAvailable = 0;
  ULONGLONG totalBytes = 0;
  ULONGLONG freeBytes = 0;
  NTSTATUS status = STATUS_NOT_IMPLEMENTED;

  ULONG allocationUnitSize = FileInfo->DokanOptions->AllocationUnitSize;
  ULONG sectorSize = FileInfo->DokanOptions->SectorSize;

  PFILE_FS_FULL_SIZE_INFORMATION sizeInfo =
      (PFILE_FS_FULL_SIZE_INFORMATION)EventInfo->Buffer;

  if (EventContext->Operation.Volume.BufferLength <
      sizeof(FILE_FS_FULL_SIZE_INFORMATION)) {
    return STATUS_BUFFER_OVERFLOW;
  }

  if (DokanOperations->GetDiskFreeSpace) {
    status = DokanOperations->GetDiskFreeSpace(
        &freeBytesAvailable, // FreeBytesAvailable
        &totalBytes,         // TotalNumberOfBytes
        &freeBytes,          // TotalNumberOfFreeBytes
        FileInfo);
  }

  if (status == STATUS_NOT_IMPLEMENTED) {
    status = DokanGetDiskFreeSpace(&freeBytesAvailable, // FreeBytesAvailable
                                   &totalBytes,         // TotalNumberOfBytes
                                   &freeBytes, // TotalNumberOfFreeBytes
                                   FileInfo);
  }

  if (status != STATUS_SUCCESS) {
    return status;
  }

  sizeInfo->TotalAllocationUnits.QuadPart =
      totalBytes / allocationUnitSize;
  sizeInfo->ActualAvailableAllocationUnits.QuadPart =
      freeBytes / allocationUnitSize;
  sizeInfo->CallerAvailableAllocationUnits.QuadPart =
      freeBytesAvailable / allocationUnitSize;
  sizeInfo->SectorsPerAllocationUnit =
	  allocationUnitSize / sectorSize;
  sizeInfo->BytesPerSector = sectorSize;

  EventInfo->BufferLength = sizeof(FILE_FS_FULL_SIZE_INFORMATION);

  return STATUS_SUCCESS;
}
Example #5
0
NTSTATUS
DokanSetBasicInformation(
	 PEVENT_CONTEXT		EventContext,
	 PDOKAN_FILE_INFO	FileInfo,
	 PDOKAN_OPERATIONS	DokanOperations)
{
	FILETIME creation, lastAccess, lastWrite;
	NTSTATUS status = STATUS_NOT_IMPLEMENTED;

	PFILE_BASIC_INFORMATION basicInfo =
		(PFILE_BASIC_INFORMATION)((PCHAR)EventContext + EventContext->Operation.SetFile.BufferOffset);

	if (!DokanOperations->SetFileAttributes)
		return STATUS_NOT_IMPLEMENTED;
	
	if (!DokanOperations->SetFileTime)
		return STATUS_NOT_IMPLEMENTED;

	status = DokanOperations->SetFileAttributes(
		EventContext->Operation.SetFile.FileName,
		basicInfo->FileAttributes,
		FileInfo);

	if (status > 0)
		return status;

	creation.dwLowDateTime = basicInfo->CreationTime.LowPart;
	creation.dwHighDateTime = basicInfo->CreationTime.HighPart;
	lastAccess.dwLowDateTime = basicInfo->LastAccessTime.LowPart;
	lastAccess.dwHighDateTime = basicInfo->LastAccessTime.HighPart;
	lastWrite.dwLowDateTime = basicInfo->LastWriteTime.LowPart;
	lastWrite.dwHighDateTime = basicInfo->LastWriteTime.HighPart;


	return DokanOperations->SetFileTime(
		EventContext->Operation.SetFile.FileName,
		&creation,
		&lastAccess,
		&lastWrite,
		FileInfo);
}
Example #6
0
NTSTATUS
DokanSetValidDataLengthInformation(
	PEVENT_CONTEXT		EventContext,
	PDOKAN_FILE_INFO	FileInfo,
	PDOKAN_OPERATIONS	DokanOperations)
{
	PFILE_VALID_DATA_LENGTH_INFORMATION validInfo =
		(PFILE_VALID_DATA_LENGTH_INFORMATION)((PCHAR)EventContext + EventContext->Operation.SetFile.BufferOffset);

	if (!DokanOperations->SetEndOfFile)
		return STATUS_NOT_IMPLEMENTED;

	return DokanOperations->SetEndOfFile(
		EventContext->Operation.SetFile.FileName,
		validInfo->ValidDataLength.QuadPart,
		FileInfo);
}
Example #7
0
NTSTATUS
DokanSetEndOfFileInformation(
	 PEVENT_CONTEXT		EventContext,
	 PDOKAN_FILE_INFO	FileInfo,
	 PDOKAN_OPERATIONS	DokanOperations)
{
	PFILE_END_OF_FILE_INFORMATION endInfo =
		(PFILE_END_OF_FILE_INFORMATION)((PCHAR)EventContext + EventContext->Operation.SetFile.BufferOffset);

	if (!DokanOperations->SetEndOfFile)
		return STATUS_NOT_IMPLEMENTED;

	return DokanOperations->SetEndOfFile(
		EventContext->Operation.SetFile.FileName,
		endInfo->EndOfFile.QuadPart,
		FileInfo);
}
Example #8
0
ULONG
DokanFsFullSizeInformation(
	PEVENT_INFORMATION	EventInfo,
	PEVENT_CONTEXT		EventContext,
	PDOKAN_FILE_INFO	FileInfo,
	PDOKAN_OPERATIONS	DokanOperations)
{
	ULONGLONG	freeBytesAvailable = 0;
	ULONGLONG	totalBytes = 0;
	ULONGLONG	freeBytes = 0;
	
	int			status = -1;

	PFILE_FS_FULL_SIZE_INFORMATION sizeInfo = (PFILE_FS_FULL_SIZE_INFORMATION)EventInfo->Buffer;

	
	if (!DokanOperations->GetDiskFreeSpace) {
		DokanOperations->GetDiskFreeSpace = DokanGetDiskFreeSpace;
		//return STATUS_NOT_IMPLEMENTED;
	}

	if (EventContext->Operation.Volume.BufferLength < sizeof(FILE_FS_FULL_SIZE_INFORMATION)) {
		return STATUS_BUFFER_OVERFLOW;
	}

	status = DokanOperations->GetDiskFreeSpace(
		&freeBytesAvailable, // FreeBytesAvailable
		&totalBytes, // TotalNumberOfBytes
		&freeBytes, // TotalNumberOfFreeBytes
		FileInfo);

	if (status < 0) {
		return STATUS_INVALID_PARAMETER;
	}

	sizeInfo->TotalAllocationUnits.QuadPart		= totalBytes / DOKAN_ALLOCATION_UNIT_SIZE;
	sizeInfo->ActualAvailableAllocationUnits.QuadPart = freeBytes / DOKAN_ALLOCATION_UNIT_SIZE;
	sizeInfo->CallerAvailableAllocationUnits.QuadPart = freeBytesAvailable / DOKAN_ALLOCATION_UNIT_SIZE;
	sizeInfo->SectorsPerAllocationUnit			= DOKAN_ALLOCATION_UNIT_SIZE / DOKAN_SECTOR_SIZE;
	sizeInfo->BytesPerSector					= DOKAN_SECTOR_SIZE;

	EventInfo->BufferLength = sizeof(FILE_FS_FULL_SIZE_INFORMATION);

	return STATUS_SUCCESS;
}
Example #9
0
NTSTATUS
DokanFsVolumeInformation(PEVENT_INFORMATION EventInfo,
                         PEVENT_CONTEXT EventContext, PDOKAN_FILE_INFO FileInfo,
                         PDOKAN_OPERATIONS DokanOperations) {
  WCHAR volumeName[MAX_PATH];
  DWORD volumeSerial = 0;
  DWORD maxComLength = 0;
  DWORD fsFlags = 0;
  WCHAR fsName[MAX_PATH];
  ULONG remainingLength;
  ULONG bytesToCopy;
  NTSTATUS status = STATUS_NOT_IMPLEMENTED;

  PFILE_FS_VOLUME_INFORMATION volumeInfo =
      (PFILE_FS_VOLUME_INFORMATION)EventInfo->Buffer;

  remainingLength = EventContext->Operation.Volume.BufferLength;

  if (remainingLength < sizeof(FILE_FS_VOLUME_INFORMATION)) {
    return STATUS_BUFFER_OVERFLOW;
  }

  RtlZeroMemory(volumeName, sizeof(volumeName));
  RtlZeroMemory(fsName, sizeof(fsName));

  if (DokanOperations->GetVolumeInformation) {
    status = DokanOperations->GetVolumeInformation(
        volumeName,                         // VolumeNameBuffer
        sizeof(volumeName) / sizeof(WCHAR), // VolumeNameSize
        &volumeSerial,                      // VolumeSerialNumber
        &maxComLength,                      // MaximumComponentLength
        &fsFlags,                           // FileSystemFlags
        fsName,                             // FileSystemNameBuffer
        sizeof(fsName) / sizeof(WCHAR),     // FileSystemNameSize
        FileInfo);
  }

  if (status == STATUS_NOT_IMPLEMENTED) {
    status = DokanGetVolumeInformation(
        volumeName,                         // VolumeNameBuffer
        sizeof(volumeName) / sizeof(WCHAR), // VolumeNameSize
        &volumeSerial,                      // VolumeSerialNumber
        &maxComLength,                      // MaximumComponentLength
        &fsFlags,                           // FileSystemFlags
        fsName,                             // FileSystemNameBuffer
        sizeof(fsName) / sizeof(WCHAR),     // FileSystemNameSize
        FileInfo);
  }

  if (status != STATUS_SUCCESS) {
    return status;
  }

  volumeInfo->VolumeCreationTime.QuadPart = 0;
  volumeInfo->VolumeSerialNumber = volumeSerial;
  volumeInfo->SupportsObjects = FALSE;

  remainingLength -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]);

  bytesToCopy = (ULONG)wcslen(volumeName) * sizeof(WCHAR);
  if (remainingLength < bytesToCopy) {
    bytesToCopy = remainingLength;
  }

  volumeInfo->VolumeLabelLength = bytesToCopy;
  RtlCopyMemory(volumeInfo->VolumeLabel, volumeName, bytesToCopy);
  remainingLength -= bytesToCopy;

  EventInfo->BufferLength =
      EventContext->Operation.Volume.BufferLength - remainingLength;

  return STATUS_SUCCESS;
}
Example #10
0
ULONG
DokanFsAttributeInformation(
	PEVENT_INFORMATION	EventInfo,
	PEVENT_CONTEXT		EventContext,
	PDOKAN_FILE_INFO	FileInfo,
	PDOKAN_OPERATIONS	DokanOperations)
{
	WCHAR	volumeName[MAX_PATH];
	DWORD	volumeSerial;
	DWORD	maxComLength;
	DWORD	fsFlags;
	WCHAR	fsName[MAX_PATH];
	ULONG	remainingLength;
	ULONG	bytesToCopy;

	int		status = -1;

	PFILE_FS_ATTRIBUTE_INFORMATION attrInfo = 
		(PFILE_FS_ATTRIBUTE_INFORMATION)EventInfo->Buffer;
	
	if (!DokanOperations->GetVolumeInformation) {
		DokanOperations->GetVolumeInformation = DokanGetVolumeInformation;
		//return STATUS_NOT_IMPLEMENTED;
	}

	remainingLength = EventContext->Operation.Volume.BufferLength;

	if (remainingLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION)) {
		return STATUS_BUFFER_OVERFLOW;
	}


	RtlZeroMemory(volumeName, sizeof(volumeName));
	RtlZeroMemory(fsName, sizeof(fsName));

	status = DokanOperations->GetVolumeInformation(
				volumeName,			// VolumeNameBuffer
				sizeof(volumeName) / sizeof(WCHAR),	// VolumeNameSize
				&volumeSerial,		// VolumeSerialNumber
				&maxComLength,		// MaximumComponentLength
				&fsFlags,			// FileSystemFlags
				fsName,				// FileSystemNameBuffer
				sizeof(fsName) / sizeof(WCHAR),		// FileSystemNameSize
				FileInfo);

	if (status < 0) {
		return STATUS_INVALID_PARAMETER;
	}


	attrInfo->FileSystemAttributes = fsFlags;
	attrInfo->MaximumComponentNameLength = maxComLength;

	remainingLength -= FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName[0]);
	
	bytesToCopy = (ULONG)wcslen(fsName) * sizeof(WCHAR);
	if (remainingLength < bytesToCopy) {
		bytesToCopy = remainingLength;
	}

	attrInfo->FileSystemNameLength = bytesToCopy;
	RtlCopyMemory(attrInfo->FileSystemName, fsName, bytesToCopy);
	remainingLength -= bytesToCopy;

	EventInfo->BufferLength = EventContext->Operation.Volume.BufferLength - remainingLength;
	
	return STATUS_SUCCESS;
}