Exemplo n.º 1
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Set file position
 *
 * @v This			File handle
 * @v Position		New file position
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileSetPosition(EFI_FILE_HANDLE This, UINT64 Position)
{
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);
	UINT64 FileSize;

	PrintInfo(L"SetPosition(%llx|'%s', %lld) %s\n", (UINT64) This,
		FileName(File), Position, (File->IsDir)?L"<DIR>":L"");

	/* If this is a directory, reset the Index to the start */
	if (File->IsDir) {
		if (Position != 0)
			return EFI_INVALID_PARAMETER;
		File->DirIndex = 0;
		return EFI_SUCCESS;
	}

	/* Fail if we attempt to seek past the end of the file (since
	 * we do not support writes).
	 */
	FileSize = GrubGetFileSize(File);
	if (Position > FileSize) {
		PrintError(L"'%s': Cannot seek to %#llx of %llx\n",
				FileName(File), Position, FileSize);
		return EFI_UNSUPPORTED;
	}

	/* Set position */
	GrubSetFileOffset(File, Position);
	PrintDebug(L"'%s': Position set to %llx\n",
			FileName(File), Position);

	return EFI_SUCCESS;
}
Exemplo n.º 2
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Flush file modified data
 *
 * @v This			File handle
 * @v Type			Type of information
 * @v Len			Buffer size
 * @v Data			Buffer
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileFlush(EFI_FILE_HANDLE This)
{
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);

	PrintInfo(L"Flush(%llx|'%s')\n", (UINT64)This, FileName(File));
	return EFI_SUCCESS;
}
Exemplo n.º 3
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Write to file
 *
 * @v This			File handle
 * @v Len			Length to write
 * @v Data			Data buffer
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileWrite(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
{
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);

	PrintError(L"Cannot write to '%s'\n", FileName(File));
	return EFI_WRITE_PROTECTED;
}
Exemplo n.º 4
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Open root directory
 *
 * @v This			EFI simple file system
 * @ret Root		File handle for the root directory
 * @ret Status		EFI status code
 */
EFI_STATUS EFIAPI
FileOpenVolume(EFI_FILE_IO_INTERFACE *This, EFI_FILE_HANDLE *Root)
{
	EFI_FS *FSInstance = _CR(This, EFI_FS, FileIoInterface);

	PrintInfo(L"OpenVolume\n");
	*Root = &FSInstance->RootFile->EfiFile;

	return EFI_SUCCESS;
}
Exemplo n.º 5
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Set file information
 *
 * @v This			File handle
 * @v Type			Type of information
 * @v Len			Buffer size
 * @v Data			Buffer
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileSetInfo(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN Len, VOID *Data)
{
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);
	CHAR16 GuidString[36];

	GuidToString(GuidString, Type);
	PrintError(L"Cannot set information of type %s for file '%s'\n",
			GuidString, FileName(File));
	return EFI_WRITE_PROTECTED;
}
Exemplo n.º 6
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Close and delete file
 *
 * @v This			File handle
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileDelete(EFI_FILE_HANDLE This)
{
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);

	PrintError(L"Cannot delete '%s'\n", FileName(File));

	/* Close file */
	FileClose(This);

	/* Warn of failure to delete */
	return EFI_WARN_DELETE_FAILURE;
}
Exemplo n.º 7
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Get file position
 *
 * @v This			File handle
 * @ret Position	New file position
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileGetPosition(EFI_FILE_HANDLE This, UINT64 *Position)
{
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);

	PrintInfo(L"GetPosition(%llx|'%s', %lld)\n", This, FileName(File));

	if (File->IsDir)
		*Position = File->DirIndex;
	else
		*Position = GrubGetFileOffset(File);
	return EFI_SUCCESS;
}
Exemplo n.º 8
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Read from file
 *
 * @v This			File handle
 * @v Len			Length to read
 * @v Data			Data buffer
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileRead(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
{
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);

	PrintInfo(L"Read(%llx|'%s', %d) %s\n", This, FileName(File),
			*Len, File->IsDir?L"<DIR>":L"");

	/* If this is a directory, then fetch the directory entries */
	if (File->IsDir)
		return FileReadDir(File, Len, Data);

	return GrubRead(File, Data, Len);
}
//
// get partition number
//
UINT32 DevPathGetPartitionNumber(EFI_DEVICE_PATH_PROTOCOL* devicePath)
{
	while(!EfiIsDevicePathEnd(devicePath))
	{
		if(EfiDevicePathType(devicePath) == MEDIA_DEVICE_PATH && devicePath->SubType == MEDIA_HARDDRIVE_DP)
		{
			HARDDRIVE_DEVICE_PATH* hardDriveDevicePath						= _CR(devicePath, HARDDRIVE_DEVICE_PATH, Header);
			if(hardDriveDevicePath->SignatureType == SIGNATURE_TYPE_GUID && hardDriveDevicePath->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER)
				return hardDriveDevicePath->PartitionNumber;
		}

		devicePath															= EfiNextDevicePathNode(devicePath);
	}
	return static_cast<UINT32>(-1);
}
Exemplo n.º 10
0
static EFI_STATUS EFIAPI
FSBindingStop(EFI_DRIVER_BINDING_PROTOCOL *This,
		EFI_HANDLE ControllerHandle, UINTN NumberOfChildren,
		EFI_HANDLE *ChildHandleBuffer)
{
	EFI_STATUS Status;
	EFI_FS *Instance;
	EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileIoInterface;

	PrintDebug(L"FSBindingStop\n");

	/* Get a pointer back to our FS instance through its installed protocol */
	Status = BS->OpenProtocol(ControllerHandle,
			&gEfiSimpleFileSystemProtocolGuid, (VOID **) &FileIoInterface,
			This->DriverBindingHandle, ControllerHandle,
			EFI_OPEN_PROTOCOL_GET_PROTOCOL);
	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Could not locate our instance");
		return Status;
	}

	Instance = _CR(FileIoInterface, EFI_FS, FileIoInterface);
	FSUninstall(Instance, ControllerHandle);

	Status = GrubDeviceExit(Instance);
	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Could not destroy grub device");
	}

    BS->CloseProtocol(ControllerHandle, &gEfiDiskIo2ProtocolGuid,
                      This->DriverBindingHandle, ControllerHandle);

	BS->CloseProtocol(ControllerHandle, &gEfiDiskIoProtocolGuid,
			This->DriverBindingHandle, ControllerHandle);

	FreeFsInstance(Instance);

	return EFI_SUCCESS;
}
Exemplo n.º 11
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Close file
 *
 * @v This			File handle
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileClose(EFI_FILE_HANDLE This)
{
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);

	PrintInfo(L"Close(%llx|'%s') %s\n", (UINT64) This, FileName(File),
		IS_ROOT(File)?L"<ROOT>":L"");

	/* Nothing to do it this is the root */
	if (IS_ROOT(File))
		return EFI_SUCCESS;

	if (--File->RefCount == 0) {
		/* Close the file if it's a regular one */
		if (!File->IsDir)
			GrubClose(File);
		/* NB: basename points into File->path and does not need to be freed */
		FreePool(File->path);
		GrubDestroyFile(File);
	}

	return EFI_SUCCESS;
}
Exemplo n.º 12
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Open file
 *
 * @v This			File handle
 * @ret new			New file handle
 * @v Name			File name
 * @v Mode			File mode
 * @v Attributes	File attributes (for newly-created files)
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileOpen(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New,
		CHAR16 *Name, UINT64 Mode, UINT64 Attributes)
{
	EFI_STATUS Status;
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);
	EFI_GRUB_FILE *NewFile;

	// TODO: Use dynamic buffers?
	char path[MAX_PATH], clean_path[MAX_PATH], *dirname;
	INTN i, len;
	BOOLEAN AbsolutePath = (*Name == L'\\');

	PrintInfo(L"Open(%llx%s, \"%s\")\n", (UINT64) This,
			IS_ROOT(File)?L" <ROOT>":L"", Name);

	/* Fail unless opening read-only */
	if (Mode != EFI_FILE_MODE_READ) {
		PrintWarning(L"File '%s' can only be opened in read-only mode\n", Name);
		return EFI_WRITE_PROTECTED;
	}

	/* Additional failures */
	if ((StrCmp(Name, L"..") == 0) && IS_ROOT(File)) {
		PrintInfo(L"Trying to open <ROOT>'s parent\n");
		return EFI_NOT_FOUND;
	}

	/* See if we're trying to reopen current (which the EFI Shell insists on doing) */
	if ((*Name == 0) || (StrCmp(Name, L".") == 0)) {
		PrintInfo(L"  Reopening %s\n", IS_ROOT(File)?L"<ROOT>":FileName(File));
		File->RefCount++;
		*New = This;
		PrintInfo(L"  RET: %llx\n", (UINT64) *New);
		return EFI_SUCCESS;
	}

	/* If we have an absolute path, don't bother completing with the parent */
	if (AbsolutePath) {
		len = 0;
	} else {
		strcpya(path, File->path);
		len = strlena(path);
		/* Add delimiter if needed */
		if ((len == 0) || (path[len-1] != '/'))
			path[len++] = '/';
	}

	/* Copy the rest of the path (converted to UTF-8) */
	Status = Utf16ToUtf8NoAlloc(Name, &path[len], sizeof(path) - len);
	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Could not convert path to UTF-8");
		return Status;
	}
	/* Convert the delimiters */
	for (i = strlena(path) - 1 ; i >= len; i--) {
		if (path[i] == '\\')
			path[i] = '/';
	}

	/* We only want to handle with absolute paths */
	clean_path[0] = '/';
	/* Find out if we're dealing with root by removing the junk */
	CopyPathRelative(&clean_path[1], path, MAX_PATH - 1);
	if (clean_path[1] == 0) {
		/* We're dealing with the root */
		PrintInfo(L"  Reopening <ROOT>\n");
		*New = &File->FileSystem->RootFile->EfiFile;
		/* Must make sure that DirIndex is reset too (NB: no concurrent access!) */
		File->FileSystem->RootFile->DirIndex = 0;
		PrintInfo(L"  RET: %llx\n", (UINT64) *New);
		return EFI_SUCCESS;
	}

	// TODO: eventually we should seek for already opened files and increase RefCount */
	/* Allocate and initialise an instance of a file */
	Status = GrubCreateFile(&NewFile, File->FileSystem);
	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Could not instantiate file");
		return Status;
	}

	NewFile->path = AllocatePool(strlena(clean_path)+1);
	if (NewFile->path == NULL) {
		GrubDestroyFile(NewFile);
		PrintError(L"Could not instantiate path\n");
		return EFI_OUT_OF_RESOURCES;
	}
	strcpya(NewFile->path, clean_path);

	/* Isolate the basename and dirname */
	// TODO: would be nicer to have those if path.c
	for (i = strlena(clean_path) - 1; i >= 0; i--) {
		if (clean_path[i] == '/') {
			clean_path[i] = 0;
			break;
		}
	}
	dirname = (i <= 0) ? "/" : clean_path;
	NewFile->basename = &NewFile->path[i+1];

	/* Find if we're working with a directory and fill the grub timestamp */
	Status = GrubDir(NewFile, dirname, InfoHook, (VOID *) NewFile);
	if (EFI_ERROR(Status)) {
		if (Status != EFI_NOT_FOUND)
			PrintStatusError(Status, L"Could not get file attributes for '%s'", Name);
		FreePool(NewFile->path);
		GrubDestroyFile(NewFile);
		return Status;
	}

	/* Finally we can call on GRUB open() if it's a regular file */
	if (!NewFile->IsDir) {
		Status = GrubOpen(NewFile);
		if (EFI_ERROR(Status)) {
			if (Status != EFI_NOT_FOUND)
				PrintStatusError(Status, L"Could not open file '%s'", Name);
			FreePool(NewFile->path);
			GrubDestroyFile(NewFile);
			return Status;
		}
	}

	NewFile->RefCount++;
	*New = &NewFile->EfiFile;

	PrintInfo(L"  RET: %llx\n", (UINT64) *New);
	return EFI_SUCCESS;
}
Exemplo n.º 13
0
//
// get utf8 name
//
CHAR8* DevPathExtractFilePathName(EFI_DEVICE_PATH_PROTOCOL* devicePath, BOOLEAN fullPath)
{
	FILEPATH_DEVICE_PATH* startFilePath										= nullptr;
	FILEPATH_DEVICE_PATH* endFilePath										= nullptr;
	UINTN totalLength														= 0;
	while(!EfiIsDevicePathEnd(devicePath))
	{
		if(devicePath->Type == MEDIA_DEVICE_PATH && devicePath->SubType == MEDIA_FILEPATH_DP)
		{
			endFilePath														= _CR(devicePath, FILEPATH_DEVICE_PATH, Header);
			totalLength														+= DevicePathNodeLength(devicePath) - SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(CHAR16);
			if(!startFilePath)
				startFilePath												= endFilePath;
		}
		else if(startFilePath)
		{
			break;
		}

		devicePath															= EfiNextDevicePathNode(devicePath);
	}

	if(!startFilePath)
		return nullptr;

	CHAR16* pathName														= nullptr;
	CHAR16* allocatedPathName												= nullptr;
	UINTN pathLength														= 0;
	if(startFilePath != endFilePath)
	{
		allocatedPathName													= static_cast<CHAR16*>(MmAllocatePool(totalLength));
		if(!allocatedPathName)
			return nullptr;

		pathName															= allocatedPathName;
		while(TRUE)
		{
			UINTN length													= (DevicePathNodeLength(&startFilePath->Header) - SIZE_OF_FILEPATH_DEVICE_PATH) / sizeof(CHAR16);
			for(UINTN i = 0; i < length && startFilePath->PathName[i]; i ++, pathLength ++)
				pathName[pathLength]										= startFilePath->PathName[i];

			if(startFilePath == endFilePath)
				break;

			startFilePath													= _CR(EfiNextDevicePathNode(&startFilePath->Header), FILEPATH_DEVICE_PATH, Header);
		}
	}
	else
	{
		pathName															= startFilePath->PathName;
		pathLength															= (DevicePathNodeLength(&startFilePath->Header) - SIZE_OF_FILEPATH_DEVICE_PATH) / sizeof(CHAR16);
		while(!pathName[pathLength - 1] && pathLength)
			pathLength														-= 1;
	}

	CHAR16* lastDirectory													= nullptr;
	for(UINTN i = 0; i < pathLength && pathName[i]; i ++)
	{
		if(pathName[i] == L'\\' || pathName[i] == L'/')
			lastDirectory													= pathName + i;
	}

	if(lastDirectory && !fullPath)
		lastDirectory														+= 1;
	else
		lastDirectory														= pathName;

	CHAR8* retValue															= BlAllocateUtf8FromUnicode(lastDirectory, pathName + pathLength - lastDirectory);
	if(retValue)
		BlConvertPathSeparator(retValue, '/', '\\');
	if(allocatedPathName)
		MmFreePool(allocatedPathName);
	return retValue;
}
Exemplo n.º 14
0
//
// get partition handle by number
//
EFI_HANDLE DevPathGetPartitionHandleByNumber(EFI_DEVICE_PATH_PROTOCOL* referencePath, UINT32 number)
{
	UINTN nodeCount															= DevPathGetNodeCount(referencePath);
	if(!nodeCount)
		return nullptr;

	UINTN count																= 0;
	EFI_HANDLE* handleArray													= nullptr;
	if(EFI_ERROR(EfiBootServices->LocateHandleBuffer(ByProtocol, &EfiBlockIoProtocolGuid, nullptr, &count, &handleArray)))
		return nullptr;

	EFI_HANDLE retValue														= nullptr;
	for(UINTN i = 0; i < count; i ++)
	{
		EFI_HANDLE theHandle												= handleArray[i];
		if(!theHandle)
			continue;

		EFI_DEVICE_PATH_PROTOCOL* devicePath								= DevPathGetDevicePathProtocol(theHandle);
		if(!devicePath)
			continue;

		if(DevPathGetNodeCount(devicePath) != nodeCount)
			continue;

		EFI_DEVICE_PATH_PROTOCOL* pathA										= referencePath;
		EFI_DEVICE_PATH_PROTOCOL* pathB										= devicePath;
		BOOLEAN checkResult													= TRUE;
		for(UINTN i = 0; i < nodeCount && !EfiIsDevicePathEnd(pathA) && !EfiIsDevicePathEnd(pathB); i ++)
		{
			if(EfiDevicePathNodeLength(pathA) != EfiDevicePathNodeLength(pathB))
			{
				checkResult													= FALSE;
				break;
			}

		#if 0
			if(pathA->Type == MESSAGING_DEVICE_PATH && pathA->SubType == MSG_VENDOR_DP && !memcmp(pathA + 1, &EfiDevicePathMessagingSASGuid, sizeof(EFI_GUID)))
			{
				SAS_DEVICE_PATH* sasA										= _CR(pathA, SAS_DEVICE_PATH, Header);
				SAS_DEVICE_PATH* sasB										= _CR(pathB, SAS_DEVICE_PATH, Header);
				if(sasA->SasAddress != sasB->SasAddress || sasA->Lun != sasB->Lun || sasA->RelativeTargetPort != sasB->RelativeTargetPort)
				{
					checkResult												= FALSE;
					break;
				}
			}
		#endif

			if(memcmp(pathA, pathB, EfiDevicePathNodeLength(pathA)))
			{
				checkResult													= FALSE;
				break;
			}
		}
		if(!checkResult)
			continue;

		if(DevPathGetPartitionNumber(devicePath) != number)
			continue;

		retValue															= theHandle;
		break;
	}

	MmFreePool(handleArray);
	return retValue;
}
Exemplo n.º 15
0
int main(void)
{
	//CTIMER_DECLARE();
#if 0
	uint32_t memory = SRAM1_LOC;
	uint32_t lut = SRAM1_LOC;

	//while(1);
	memset((void *)QQ_LOC, 0x01, 0x3000);
	g_qqueue->writeIndex = 0;
	g_qqueue->produced = 0;
	g_qqueue->consumed = 0;

 	while(1)
 		getRLSFrame(&memory, &lut); 
#endif
#if 0
	int i = 0x12345678;
	foo(&i);
	printf("%d\n", i);
	while(1);
#endif
#if 0
	int i;
	uint32_t lut = SRAM1_LOC;
 	uint32_t memory = SRAM1_LOC+0x1000;
	uint8_t *plut = (uint8_t *)lut;
	for (i=0; i<0x4000; i++)
		plut[i] = i%5==0 ? 1 : 0;
	
 	while(1)
 		getRLSFrame(&memory, &lut); 

#endif
#if 1
	_DBG("M0 start\n");

	chirpOpen();
	exec_init();
	frame_init();
	rls_init();

#if 0
	while(1)
	{
		if (g_foo)
			loop0();
	}
#endif

#if 0
	vsync();
#endif
#if 0
	//while(g_loop);
	uint8_t type = CAM_GRAB_M1R2;
	uint32_t memory = SRAM1_LOC;
	uint16_t offset = 0;
	uint16_t width = 320;
	uint16_t height = 200;
	while(1)
	{
		 getFrame(&type, &memory, &offset, &offset, &width, &height);
		 i++;

		 if (i%50==0)
		 {
			 _DBD32(i), _CR();
		 }
	}
#endif
	//printf("M0 ready\n");
	exec_loop();
#endif
#if 0
	while(1)
	{
		CTIMER_START();
		syncM1((uint32_t *)&LPC_GPIO_PORT->PIN[1], 0x2000);
		CTIMER_STOP();
		
		printf("%d\n", CTIMER_GET());
	}	
#endif
#if 0
{
	uint32_t i;
	uint8_t *lut = (uint8_t *)SRAM1_LOC + 0x10000;
	uint32_t memory = SRAM1_LOC;
	uint32_t size = SRAM1_SIZE/2;
	for (i=0; i<0x10000; i++)
		lut[i] = 0;
	lut[0xb400] = 0;
	lut[0xb401] = 1;
	lut[0xb402] = 1;
	lut[0xb403] = 1;
	lut[0xb404] = 0;
	lut[0xb405] = 1;
	lut[0xb406] = 1;
	lut[0xb407] = 0;
	lut[0xb408] = 0;
	lut[0xb409] = 0;

	while(1)
 		getRLSFrame(&memory, &size); //, (uint32_t *)&lut);
}
#endif

return 0;
}
Exemplo n.º 16
0
Arquivo: file.c Projeto: tribals/efifs
/**
 * Get file information
 *
 * @v This			File handle
 * @v Type			Type of information
 * @v Len			Buffer size
 * @v Data			Buffer
 * @ret Status		EFI status code
 */
static EFI_STATUS EFIAPI
FileGetInfo(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data)
{
	EFI_STATUS Status;
	EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile);
	EFI_FILE_SYSTEM_INFO *FSInfo = (EFI_FILE_SYSTEM_INFO *) Data;
	EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data;
	CHAR16 GuidString[36];
	EFI_TIME Time;
	CHAR8* label;

	PrintInfo(L"GetInfo(%llx|'%s', %d) %s\n", (UINT64) This,
		FileName(File), *Len, File->IsDir?L"<DIR>":L"");

	/* Determine information to return */
	if (CompareMem(Type, &GenericFileInfo, sizeof(*Type)) == 0) {

		/* Fill file information */
		PrintExtra(L"Get regular file information\n");
		if (*Len < MINIMUM_INFO_LENGTH) {
			*Len = MINIMUM_INFO_LENGTH;
			return EFI_BUFFER_TOO_SMALL;
		}

		ZeroMem(Data, sizeof(EFI_FILE_INFO));

		Info->Attribute = EFI_FILE_READ_ONLY;
		GrubTimeToEfiTime(File->Mtime, &Time);
		CopyMem(&Info->CreateTime, &Time, sizeof(Time));
		CopyMem(&Info->LastAccessTime, &Time, sizeof(Time));
		CopyMem(&Info->ModificationTime, &Time, sizeof(Time));

		if (File->IsDir) {
			Info->Attribute |= EFI_FILE_DIRECTORY;
		} else {
			Info->FileSize = GrubGetFileSize(File);
			Info->PhysicalSize = GrubGetFileSize(File);
		}

		Status = Utf8ToUtf16NoAlloc(File->basename, Info->FileName,
				(INTN)(Info->Size - sizeof(EFI_FILE_INFO)));
		if (EFI_ERROR(Status)) {
			if (Status != EFI_BUFFER_TOO_SMALL)
				PrintStatusError(Status, L"Could not convert basename to UTF-8");
			return Status;
		}

		/* The Info struct size already accounts for the extra NUL */
		Info->Size = sizeof(EFI_FILE_INFO) + 
				StrLen(Info->FileName) * sizeof(CHAR16);
		return EFI_SUCCESS;

	} else if (CompareMem(Type, &FileSystemInfo, sizeof(*Type)) == 0) {

		/* Get file system information */
		PrintExtra(L"Get file system information\n");
		if (*Len < MINIMUM_FS_INFO_LENGTH) {
			*Len = MINIMUM_FS_INFO_LENGTH;
			return EFI_BUFFER_TOO_SMALL;
		}

		ZeroMem(Data, sizeof(EFI_FILE_INFO));
		FSInfo->Size = *Len;
		FSInfo->ReadOnly = 1;
		/* NB: This should really be cluster size, but we don't have access to that */
		FSInfo->BlockSize = File->FileSystem->BlockIo->Media->BlockSize;
		if (FSInfo->BlockSize  == 0) {
			PrintWarning(L"Corrected Media BlockSize\n");
			FSInfo->BlockSize = 512;
		}
		FSInfo->VolumeSize = (File->FileSystem->BlockIo->Media->LastBlock + 1) *
			FSInfo->BlockSize;
		/* No idea if we can easily get this for GRUB, and the device is RO anyway */
		FSInfo->FreeSpace = 0;

		Status = GrubLabel(File, &label);
		if (EFI_ERROR(Status)) {
			PrintStatusError(Status, L"Could not read disk label");
		} else {
			Status = Utf8ToUtf16NoAlloc(label, FSInfo->VolumeLabel,
					(INTN)(FSInfo->Size - sizeof(EFI_FILE_SYSTEM_INFO)));
			if (EFI_ERROR(Status)) {
				if (Status != EFI_BUFFER_TOO_SMALL)
					PrintStatusError(Status, L"Could not convert label to UTF-8");
				return Status;
			}
			Info->Size = sizeof(EFI_FILE_SYSTEM_INFO) +
					StrLen(FSInfo->VolumeLabel) * sizeof(CHAR16);
		}
		return EFI_SUCCESS;

	} else {

		GuidToString(GuidString, Type);
		PrintError(L"'%s': Cannot get information of type %s\n",
				FileName(File), GuidString);
		return EFI_UNSUPPORTED;

	}
}
Exemplo n.º 17
0
//
// append file path
//
EFI_DEVICE_PATH_PROTOCOL* DevPathAppendLastComponent(EFI_DEVICE_PATH_PROTOCOL* devicePath, CHAR8 CONST* fileName, BOOLEAN replaceLastComponent)
{
	UINTN fileNameLength													= strlen(fileName);
	UINTN length															= DevPathGetSize(devicePath) + (fileNameLength + 1) * sizeof(CHAR16);
	EFI_DEVICE_PATH_PROTOCOL* newDevicePath									= static_cast<EFI_DEVICE_PATH_PROTOCOL*>(MmAllocatePool(length));
	if(!newDevicePath)
		return nullptr;

	EFI_DEVICE_PATH_PROTOCOL* dstDevicePath									= newDevicePath;
	EFI_DEVICE_PATH_PROTOCOL* srcDevicePath									= devicePath;
	FILEPATH_DEVICE_PATH* srcFilePath										= nullptr;
	FILEPATH_DEVICE_PATH* dstFilePath										= nullptr;

	while(!EfiIsDevicePathEnd(srcDevicePath))
	{
		if(EfiDevicePathType(srcDevicePath) == MEDIA_DEVICE_PATH && srcDevicePath->SubType == MEDIA_FILEPATH_DP)
		{
			srcFilePath														= _CR(srcDevicePath, FILEPATH_DEVICE_PATH, Header);
			dstFilePath														= _CR(dstDevicePath, FILEPATH_DEVICE_PATH, Header);
		}

		memcpy(dstDevicePath, srcDevicePath, DevicePathNodeLength(srcDevicePath));
		srcDevicePath														= EfiNextDevicePathNode(srcDevicePath);
		dstDevicePath														= EfiNextDevicePathNode(dstDevicePath);
	}

	if(!srcFilePath || !dstFilePath)
	{
		MmFreePool(newDevicePath);
		return nullptr;
	}

	dstFilePath->Header.Type												= MEDIA_DEVICE_PATH;
	dstFilePath->Header.SubType												= MEDIA_FILEPATH_DP;
	UINTN writePosition														= 0;

	if(replaceLastComponent)
	{
		CHAR16* pathName													= srcFilePath->PathName;
		CHAR16* lastDirectory												= nullptr;
		UINTN pathLength													= (DevicePathNodeLength(&srcFilePath->Header) - SIZE_OF_FILEPATH_DEVICE_PATH) / sizeof(CHAR16);
		for(UINTN i = 0; i < pathLength && pathName[i]; i ++)
		{
			if(pathName[i] == L'\\' || pathName[i] == L'/')
				lastDirectory												= pathName + i;
		}

		if(lastDirectory)
			lastDirectory													+= 1;
		else
			lastDirectory													= pathName;

		writePosition														= lastDirectory - pathName;
	}
	else
	{
		writePosition														= (DevicePathNodeLength(&srcFilePath->Header) - SIZE_OF_FILEPATH_DEVICE_PATH) / sizeof(CHAR16);
		while(!srcFilePath->PathName[writePosition - 1] && writePosition)
			writePosition													-= 1;
	}

	UINTN usedLength														= ArchConvertPointerToAddress(dstFilePath->PathName + writePosition) - ArchConvertPointerToAddress(newDevicePath);
	BlUtf8ToUnicode(fileName, fileNameLength, dstFilePath->PathName + writePosition, (length - usedLength - END_DEVICE_PATH_LENGTH) / sizeof(CHAR16));
	UINTN nodeLength														= SIZE_OF_FILEPATH_DEVICE_PATH + (wcslen(dstFilePath->PathName) + 1) * sizeof(CHAR16);
	SetDevicePathNodeLength(&dstFilePath->Header, nodeLength);
	EFI_DEVICE_PATH_PROTOCOL* endOfPath										= NextDevicePathNode(&dstFilePath->Header);
	SetDevicePathEndNode(endOfPath);
	return newDevicePath;
}