Add Socket Libraries.
Add Posix functions for porting compatibility. Fix compliance issues with ISO/IEC 9899:199409 New Functions: setenv(), fparseln(), GetFileNameFromPath(), rename(), realpath(), setprogname(), getprogname(), strlcat(), strlcpy(), strsep(), setitimer(), getitimer(), timegm(), getopt(), basename(), mkstemp(), ffs(), vsnprintf(), snprintf(), getpass(), usleep(), select(), writev(), strcasecmp(), getcwd(), chdir(), tcgetpgrp(), getpgrp(), gettimeofday(), bcopy(), git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12061 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -45,6 +45,12 @@ static const int stdioFlags[NUM_SPECIAL] = {
|
||||
static DeviceNode *ConNode[NUM_SPECIAL];
|
||||
static ConInstance *ConInstanceList;
|
||||
|
||||
static wchar_t *ConReadBuf;
|
||||
|
||||
/* Flags settable by Ioctl */
|
||||
static BOOLEAN TtyCooked;
|
||||
static BOOLEAN TtyEcho;
|
||||
|
||||
ssize_t
|
||||
WideTtyCvt( CHAR16 *dest, const char *buf, size_t n)
|
||||
{
|
||||
@@ -127,74 +133,6 @@ da_ConSeek(
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
ssize_t
|
||||
EFIAPI
|
||||
da_ConRead(
|
||||
IN OUT struct __filedes *filp,
|
||||
IN OUT off_t *offset, // Console ignores this
|
||||
IN size_t BufferSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto;
|
||||
ConInstance *Stream;
|
||||
CHAR16 *OutPtr;
|
||||
EFI_INPUT_KEY Key;
|
||||
UINTN NumChar;
|
||||
UINTN Edex;
|
||||
EFI_STATUS Status = RETURN_SUCCESS;
|
||||
UINTN i;
|
||||
|
||||
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1; // Looks like a bad This pointer
|
||||
}
|
||||
if(Stream->InstanceNum != STDIN_FILENO) {
|
||||
// Read only valid for stdin
|
||||
EFIerrno = RETURN_UNSUPPORTED;
|
||||
return -1;
|
||||
}
|
||||
// It looks like things are OK for trying to read
|
||||
// We will accumulate *BufferSize characters or until we encounter
|
||||
// an "activation" character. Currently any control character.
|
||||
Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;
|
||||
OutPtr = Buffer;
|
||||
NumChar = (BufferSize - 1) / sizeof(CHAR16);
|
||||
i = 0;
|
||||
do {
|
||||
if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {
|
||||
Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
Status = Proto->ReadKeyStroke(Proto, &Key);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Key.ScanCode = Stream->UnGetKey.ScanCode;
|
||||
Key.UnicodeChar = Stream->UnGetKey.UnicodeChar;
|
||||
Stream->UnGetKey.ScanCode = SCAN_NULL;
|
||||
Stream->UnGetKey.UnicodeChar = CHAR_NULL;
|
||||
}
|
||||
if(Key.ScanCode == SCAN_NULL) {
|
||||
*OutPtr++ = Key.UnicodeChar;
|
||||
++i;
|
||||
}
|
||||
if(iswcntrl(Key.UnicodeChar)) { // If a control character, or a scan code
|
||||
break;
|
||||
}
|
||||
} while(i < NumChar);
|
||||
|
||||
*OutPtr = L'\0'; // Terminate the input buffer
|
||||
EFIerrno = Status;
|
||||
return (ssize_t)(i * sizeof(CHAR16)); // Will be 0 if we didn't get a key
|
||||
}
|
||||
|
||||
/* Write a NULL terminated WCS to the EFI console.
|
||||
|
||||
@param[in,out] BufferSize Number of bytes in Buffer. Set to zero if
|
||||
@@ -265,6 +203,109 @@ da_ConWrite(
|
||||
return BufferSize;
|
||||
}
|
||||
|
||||
/** Read characters from the console input device.
|
||||
|
||||
@param[in,out] filp Pointer to file descriptor for this file.
|
||||
@param[in,out] offset Ignored.
|
||||
@param[in] BufferSize Buffer size, in bytes.
|
||||
@param[out] Buffer Buffer in which to place the read characters.
|
||||
|
||||
@return Number of bytes actually placed into Buffer.
|
||||
|
||||
@todo Handle encodings other than ASCII-7 and UEFI.
|
||||
**/
|
||||
static
|
||||
ssize_t
|
||||
EFIAPI
|
||||
da_ConRead(
|
||||
IN OUT struct __filedes *filp,
|
||||
IN OUT off_t *offset, // Console ignores this
|
||||
IN size_t BufferSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto;
|
||||
ConInstance *Stream;
|
||||
wchar_t *OutPtr;
|
||||
EFI_INPUT_KEY Key;
|
||||
UINTN NumChar;
|
||||
UINTN Edex;
|
||||
EFI_STATUS Status = RETURN_SUCCESS;
|
||||
UINTN i;
|
||||
char EchoBuff[MB_CUR_MAX + 1];
|
||||
int NumEcho;
|
||||
|
||||
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1; // Looks like a bad This pointer
|
||||
}
|
||||
if(Stream->InstanceNum != STDIN_FILENO) {
|
||||
// Read only valid for stdin
|
||||
EFIerrno = RETURN_UNSUPPORTED;
|
||||
return -1;
|
||||
}
|
||||
// It looks like things are OK for trying to read
|
||||
// We will accumulate *BufferSize characters or until we encounter
|
||||
// an "activation" character. Currently any control character.
|
||||
Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;
|
||||
OutPtr = ConReadBuf;
|
||||
NumChar = (BufferSize > MAX_INPUT)? MAX_INPUT : BufferSize;
|
||||
i = 0;
|
||||
do {
|
||||
if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {
|
||||
Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
Status = Proto->ReadKeyStroke(Proto, &Key);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Key.ScanCode = Stream->UnGetKey.ScanCode;
|
||||
Key.UnicodeChar = Stream->UnGetKey.UnicodeChar;
|
||||
Stream->UnGetKey.ScanCode = SCAN_NULL;
|
||||
Stream->UnGetKey.UnicodeChar = CHAR_NULL;
|
||||
}
|
||||
if(Key.ScanCode == SCAN_NULL) {
|
||||
NumEcho = 0;
|
||||
if(TtyCooked && (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {
|
||||
*OutPtr++ = CHAR_LINEFEED;
|
||||
NumEcho = wctomb(EchoBuff, CHAR_LINEFEED);
|
||||
}
|
||||
else {
|
||||
*OutPtr++ = Key.UnicodeChar;
|
||||
NumEcho = wctomb(EchoBuff, Key.UnicodeChar);
|
||||
}
|
||||
++i;
|
||||
EchoBuff[NumEcho] = 0; /* Terminate the Echo buffer */
|
||||
if(TtyEcho) {
|
||||
/* Echo the character just input */
|
||||
da_ConWrite(&gMD->fdarray[STDOUT_FILENO], NULL, 2, EchoBuff);
|
||||
}
|
||||
}
|
||||
if(iswcntrl(Key.UnicodeChar)) { // If a control character, or a scan code
|
||||
break;
|
||||
}
|
||||
} while(i < NumChar);
|
||||
|
||||
*OutPtr = L'\0'; // Terminate the input buffer
|
||||
|
||||
/* Convert the input buffer and place in Buffer.
|
||||
If the fully converted input buffer won't fit, write what will and
|
||||
leave the rest in ConReadBuf with ConReadLeft indicating how many
|
||||
unconverted characters remain in ConReadBuf.
|
||||
*/
|
||||
NumEcho = (int)wcstombs(Buffer, ConReadBuf, BufferSize); /* Re-use NumEcho to hold number of bytes in Buffer */
|
||||
/* More work needs to be done before locales other than C can be supported. */
|
||||
|
||||
EFIerrno = Status;
|
||||
return (ssize_t)NumEcho; // Will be 0 if we didn't get a key
|
||||
}
|
||||
|
||||
/** Console-specific helper function for the fstat() function.
|
||||
|
||||
st_size Set to number of characters read for stdin and number written for stdout and stderr.
|
||||
@@ -347,27 +388,28 @@ da_ConIoctl(
|
||||
int
|
||||
EFIAPI
|
||||
da_ConOpen(
|
||||
DeviceNode *DevNode,
|
||||
struct __filedes *filp,
|
||||
void *DevInstance,
|
||||
int DevInstance, // Not used for console devices
|
||||
wchar_t *Path, // Not used for console devices
|
||||
wchar_t *Flags // Not used for console devices
|
||||
wchar_t *MPath // Not used for console devices
|
||||
)
|
||||
{
|
||||
ConInstance *Stream;
|
||||
|
||||
if((filp == NULL) ||
|
||||
(DevInstance == NULL))
|
||||
(DevNode == NULL))
|
||||
{
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1;
|
||||
}
|
||||
Stream = (ConInstance *)DevInstance;
|
||||
Stream = (ConInstance *)DevNode->InstanceList;
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1; // Looks like a bad This pointer
|
||||
}
|
||||
gMD->StdIo[Stream->InstanceNum] = (ConInstance *)DevInstance;
|
||||
gMD->StdIo[Stream->InstanceNum] = Stream;
|
||||
filp->f_iflags |= (S_IFREG | _S_IFCHR | _S_ICONSOLE);
|
||||
filp->f_offset = 0;
|
||||
filp->f_ops = &Stream->Abstraction;
|
||||
@@ -448,7 +490,8 @@ __Cons_construct(
|
||||
int i;
|
||||
|
||||
ConInstanceList = (ConInstance *)AllocateZeroPool(NUM_SPECIAL * sizeof(ConInstance));
|
||||
if(ConInstanceList == NULL) {
|
||||
ConReadBuf = (wchar_t *)AllocateZeroPool((MAX_INPUT + 1) * sizeof(wchar_t));
|
||||
if((ConInstanceList == NULL) || (ConReadBuf == NULL)) {
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
@@ -507,6 +550,10 @@ __Cons_construct(
|
||||
}
|
||||
Stream->Parent = ConNode[i];
|
||||
}
|
||||
/* Initialize Ioctl flags until Ioctl is really implemented. */
|
||||
TtyCooked = TRUE;
|
||||
TtyEcho = TRUE;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -527,6 +574,9 @@ __Cons_deconstruct(
|
||||
if(ConInstanceList != NULL) {
|
||||
FreePool(ConInstanceList);
|
||||
}
|
||||
if(ConReadBuf != NULL) {
|
||||
FreePool(ConReadBuf);
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/syslimits.h>
|
||||
#include <kfile.h>
|
||||
#include <Device/Device.h>
|
||||
#include <MainData.h>
|
||||
@@ -321,7 +322,7 @@ da_ShellIoctl(
|
||||
void *argp ///< May be a pointer or a value
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/** Open an abstract Shell File.
|
||||
@@ -329,10 +330,11 @@ da_ShellIoctl(
|
||||
int
|
||||
EFIAPI
|
||||
da_ShellOpen(
|
||||
DeviceNode *DevNode,
|
||||
struct __filedes *filp,
|
||||
void *DevInstance,
|
||||
int DevInstance, /* Not used by Shell */
|
||||
wchar_t *Path,
|
||||
wchar_t *Flags
|
||||
wchar_t *MPath
|
||||
)
|
||||
{
|
||||
UINT64 OpenMode;
|
||||
@@ -340,8 +342,10 @@ da_ShellOpen(
|
||||
SHELL_FILE_HANDLE FileHandle;
|
||||
GenericInstance *Gip;
|
||||
char *NPath;
|
||||
wchar_t *WPath;
|
||||
RETURN_STATUS Status;
|
||||
int oflags;
|
||||
int retval;
|
||||
|
||||
EFIerrno = RETURN_SUCCESS;
|
||||
|
||||
@@ -356,6 +360,23 @@ da_ShellOpen(
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Re-create the full mapped path for the shell. */
|
||||
if(MPath != NULL) {
|
||||
WPath = AllocateZeroPool(PATH_MAX * sizeof(wchar_t) + 1);
|
||||
if(WPath == NULL) {
|
||||
errno = ENOMEM;
|
||||
EFIerrno = RETURN_OUT_OF_RESOURCES;
|
||||
return -1;
|
||||
}
|
||||
wcsncpy(WPath, MPath, NAME_MAX); /* Get the Map Name */
|
||||
wcsncat(WPath, Path, (PATH_MAX - NAME_MAX)); /* Append the path */
|
||||
}
|
||||
else {
|
||||
WPath = Path;
|
||||
}
|
||||
|
||||
retval = -1; /* Initially assume failure. */
|
||||
|
||||
/* Do we care if the file already exists?
|
||||
If O_TRUNC, then delete the file. It will be created anew subsequently.
|
||||
If O_EXCL, then error if the file exists and O_CREAT is set.
|
||||
@@ -363,23 +384,24 @@ da_ShellOpen(
|
||||
!!!!!!!!! Change this to use ShellSetFileInfo() to actually truncate the file
|
||||
!!!!!!!!! instead of deleting and re-creating it.
|
||||
*/
|
||||
do { /* Do fake exception handling */
|
||||
if((oflags & O_TRUNC) || ((oflags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) {
|
||||
Status = ShellIsFile( Path );
|
||||
Status = ShellIsFile( WPath );
|
||||
if(Status == RETURN_SUCCESS) {
|
||||
// The file exists
|
||||
if(oflags & O_TRUNC) {
|
||||
NPath = AllocateZeroPool(1024);
|
||||
NPath = AllocateZeroPool(PATH_MAX);
|
||||
if(NPath == NULL) {
|
||||
errno = ENOMEM;
|
||||
EFIerrno = RETURN_OUT_OF_RESOURCES;
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
wcstombs(NPath, Path, 1024);
|
||||
wcstombs(NPath, WPath, PATH_MAX);
|
||||
// We do a truncate by deleting the existing file and creating a new one.
|
||||
if(unlink(NPath) != 0) {
|
||||
filp->f_iflags = 0; // Release our reservation on this FD
|
||||
FreePool(NPath);
|
||||
return -1; // errno and EFIerrno are already set.
|
||||
break;
|
||||
}
|
||||
FreePool(NPath);
|
||||
}
|
||||
@@ -387,32 +409,40 @@ da_ShellOpen(
|
||||
errno = EEXIST;
|
||||
EFIerrno = RETURN_ACCESS_DENIED;
|
||||
filp->f_iflags = 0; // Release our reservation on this FD
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the EFI Shell's Open function
|
||||
Status = ShellOpenFileByName( Path, &FileHandle, OpenMode, Attributes);
|
||||
Status = ShellOpenFileByName( WPath, &FileHandle, OpenMode, Attributes);
|
||||
if(RETURN_ERROR(Status)) {
|
||||
filp->f_iflags = 0; // Release our reservation on this FD
|
||||
// Set errno based upon Status
|
||||
errno = EFI2errno(Status);
|
||||
EFIerrno = Status;
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
retval = 0;
|
||||
// Successfully got a regular File
|
||||
filp->f_iflags |= S_IFREG;
|
||||
|
||||
// Update the info in the fd
|
||||
filp->devdata = (void *)FileHandle;
|
||||
|
||||
Gip = (GenericInstance *)DevInstance;
|
||||
Gip = (GenericInstance *)DevNode->InstanceList;
|
||||
filp->f_offset = 0;
|
||||
filp->f_ops = &Gip->Abstraction;
|
||||
// filp->devdata = FileHandle;
|
||||
// filp->devdata = FileHandle;
|
||||
} while(FALSE);
|
||||
|
||||
return 0;
|
||||
/* If we get this far, WPath is not NULL.
|
||||
If MPath is not NULL, then WPath was allocated so we need to free it.
|
||||
*/
|
||||
if(MPath != NULL) {
|
||||
FreePool(WPath);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#include <sys/poll.h>
|
||||
@@ -468,9 +498,10 @@ da_ShellRename(
|
||||
RETURN_STATUS Status;
|
||||
EFI_FILE_INFO *NewFileInfo;
|
||||
EFI_FILE_INFO *OldFileInfo;
|
||||
char *NewFn;
|
||||
wchar_t *NewFn;
|
||||
int OldFd;
|
||||
SHELL_FILE_HANDLE FileHandle;
|
||||
wchar_t *NormalizedPath;
|
||||
|
||||
// Open old file
|
||||
OldFd = open(from, O_RDWR, 0);
|
||||
@@ -482,22 +513,20 @@ da_ShellRename(
|
||||
OldFileInfo = ShellGetFileInfo( FileHandle);
|
||||
if(OldFileInfo != NULL) {
|
||||
// Copy the Old file info into our new buffer, and free the old.
|
||||
memcpy(OldFileInfo, NewFileInfo, sizeof(EFI_FILE_INFO));
|
||||
memcpy(NewFileInfo, OldFileInfo, sizeof(EFI_FILE_INFO));
|
||||
FreePool(OldFileInfo);
|
||||
// Normalize path and convert to WCS.
|
||||
NormalizedPath = NormalizePath(to);
|
||||
if (NormalizedPath != NULL) {
|
||||
// Strip off all but the file name portion of new
|
||||
NewFn = strrchr(to, '/');
|
||||
if(NewFn == NULL) {
|
||||
NewFn = strrchr(to, '\\');
|
||||
if(NewFn == NULL) {
|
||||
NewFn = (char *)to;
|
||||
}
|
||||
}
|
||||
// Convert new name from MBCS to WCS
|
||||
(void)AsciiStrToUnicodeStr( NewFn, gMD->UString);
|
||||
NewFn = GetFileNameFromPath(NormalizedPath);
|
||||
// Copy the new file name into our new file info buffer
|
||||
wcsncpy(NewFileInfo->FileName, gMD->UString, wcslen(gMD->UString)+1);
|
||||
wcsncpy(NewFileInfo->FileName, NewFn, wcslen(NewFn) + 1);
|
||||
// Update the size of the structure.
|
||||
NewFileInfo->Size = sizeof(EFI_FILE_INFO) + StrSize(NewFn);
|
||||
// Apply the new file name
|
||||
Status = ShellSetFileInfo(FileHandle, NewFileInfo);
|
||||
free(NormalizedPath);
|
||||
free(NewFileInfo);
|
||||
if(Status == EFI_SUCCESS) {
|
||||
// File has been successfully renamed. We are DONE!
|
||||
@@ -507,6 +536,12 @@ da_ShellRename(
|
||||
EFIerrno = Status;
|
||||
}
|
||||
else {
|
||||
free(NewFileInfo);
|
||||
errno = ENOMEM;
|
||||
}
|
||||
}
|
||||
else {
|
||||
free(NewFileInfo);
|
||||
errno = EIO;
|
||||
}
|
||||
}
|
||||
@@ -619,7 +654,7 @@ __ctor_DevShell(
|
||||
Stream->Abstraction.fo_poll = &da_ShellPoll;
|
||||
Stream->Abstraction.fo_flush = &fnullop_flush;
|
||||
Stream->Abstraction.fo_stat = &da_ShellStat;
|
||||
Stream->Abstraction.fo_ioctl = &fbadop_ioctl;
|
||||
Stream->Abstraction.fo_ioctl = &da_ShellIoctl;
|
||||
Stream->Abstraction.fo_delete = &da_ShellDelete;
|
||||
Stream->Abstraction.fo_rmdir = &da_ShellRmdir;
|
||||
Stream->Abstraction.fo_mkdir = &da_ShellMkdir;
|
||||
|
@@ -31,33 +31,33 @@ DeviceNode *daCurrentDevice = NULL; ///< Device currently being accessed
|
||||
fnullop_* Does nothing and returns success.
|
||||
fbadop_* Does nothing and returns EPERM
|
||||
*/
|
||||
int fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4)
|
||||
int EFIAPI fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4)
|
||||
{ return 0; }
|
||||
|
||||
short fnullop_poll (struct __filedes *filp, short Events)
|
||||
short EFIAPI fnullop_poll (struct __filedes *filp, short Events)
|
||||
{
|
||||
return ((POLLIN | POLLRDNORM | POLLOUT) & Events);
|
||||
}
|
||||
|
||||
int fnullop_flush (struct __filedes *filp)
|
||||
int EFIAPI fnullop_flush (struct __filedes *filp)
|
||||
{ return 0; }
|
||||
|
||||
int fbadop_stat (struct __filedes *filp, struct stat *StatBuf, void *Buf)
|
||||
int EFIAPI fbadop_stat (struct __filedes *filp, struct stat *StatBuf, void *Buf)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_ioctl (struct __filedes *filp, ULONGN Cmd, void *argp)
|
||||
int EFIAPI fbadop_ioctl (struct __filedes *filp, ULONGN Cmd, void *argp)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_delete (struct __filedes *filp)
|
||||
int EFIAPI fbadop_delete (struct __filedes *filp)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_mkdir (const char *path, __mode_t perms)
|
||||
int EFIAPI fbadop_mkdir (const char *path, __mode_t perms)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_rename (const char *from, const char *to)
|
||||
int EFIAPI fbadop_rename (const char *from, const char *to)
|
||||
{ return -EPERM; }
|
||||
|
||||
int fbadop_rmdir (struct __filedes *filp)
|
||||
int EFIAPI fbadop_rmdir (struct __filedes *filp)
|
||||
{ return -EPERM; }
|
||||
|
||||
/** Add a new device to the device list.
|
||||
|
@@ -248,10 +248,16 @@ PathAlias(
|
||||
|
||||
/** Parse a path producing the target device, device instance, and file path.
|
||||
|
||||
It is the caller's responsibility to free() FullPath and MapPath when they
|
||||
are no longer needed.
|
||||
|
||||
@param[in] path
|
||||
@param[out] FullPath
|
||||
@param[out] DevNode
|
||||
@param[out] Which
|
||||
@param[out] MapPath OPTIONAL. If not NULL, it points to the place to save a pointer
|
||||
to the extracted map name. If the path didn't have a map name,
|
||||
then *MapPath is set to NULL.
|
||||
|
||||
@retval RETURN_SUCCESS The path was parsed successfully.
|
||||
@retval RETURN_NOT_FOUND The path does not map to a valid device.
|
||||
@@ -266,7 +272,8 @@ ParsePath(
|
||||
IN const char *path,
|
||||
OUT wchar_t **FullPath,
|
||||
OUT DeviceNode **DevNode,
|
||||
OUT int *Which
|
||||
OUT int *Which,
|
||||
OUT wchar_t **MapPath
|
||||
)
|
||||
{
|
||||
int MapLen;
|
||||
@@ -301,7 +308,7 @@ reclassify:
|
||||
// Get the Map Name, including the trailing ':'. */
|
||||
MPath = calloc(MapLen+2, sizeof(wchar_t));
|
||||
if(MPath != NULL) {
|
||||
wmemcpy(MPath, WPath, MapLen+2);
|
||||
wmemcpy(MPath, WPath, MapLen+1);
|
||||
}
|
||||
else {
|
||||
errno = ENOMEM;
|
||||
@@ -346,6 +353,12 @@ reclassify:
|
||||
if(!RETURN_ERROR(Status)) {
|
||||
*FullPath = WPath;
|
||||
*Which = Instance;
|
||||
if(MapPath != NULL) {
|
||||
*MapPath = MPath;
|
||||
}
|
||||
else if(MPath != NULL) {
|
||||
free(MPath); /* Caller doesn't want it so let MPath go free */
|
||||
}
|
||||
|
||||
/* At this point, WPath is an absolute path,
|
||||
MPath is either NULL or points to the Map Name,
|
||||
@@ -359,6 +372,9 @@ reclassify:
|
||||
if(Node != NULL) {
|
||||
Status = RETURN_SUCCESS;
|
||||
}
|
||||
else {
|
||||
Status = RETURN_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* This is a mapped path. */
|
||||
@@ -375,8 +391,41 @@ reclassify:
|
||||
*DevNode = Node;
|
||||
}
|
||||
}
|
||||
if(MPath != NULL) {
|
||||
free(MPath); // We don't need this any more.
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Parses a normalized wide character path and returns a pointer to the entry
|
||||
following the last \. If a \ is not found in the path the return value will
|
||||
be the same as the input value. All error conditions return NULL.
|
||||
|
||||
The behavior when passing in a path that has not been normalized is undefined.
|
||||
|
||||
@param Path - A pointer to a wide character string containing a path to a
|
||||
directory or a file.
|
||||
|
||||
@return Pointer to the file name or terminal directory. NULL if an error is
|
||||
detected.
|
||||
**/
|
||||
wchar_t *
|
||||
EFIAPI
|
||||
GetFileNameFromPath (
|
||||
const wchar_t *Path
|
||||
)
|
||||
{
|
||||
wchar_t *Tail;
|
||||
|
||||
if (Path == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Tail = wcsrchr(Path, L'\\');
|
||||
if(Tail == NULL) {
|
||||
Tail = (wchar_t *) Path;
|
||||
} else {
|
||||
// Move to the next character after the '\\' to get the file name.
|
||||
Tail++;
|
||||
}
|
||||
|
||||
return Tail;
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DevConsole
|
||||
FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a
|
||||
FILE_GUID = f6937495-1f44-4a8a-8a1b-5a669f9396f6
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = DevConsole
|
||||
@@ -49,15 +49,3 @@
|
||||
[Protocols]
|
||||
gEfiSimpleTextInProtocolGuid
|
||||
gEfiSimpleTextOutProtocolGuid
|
||||
|
||||
################################################################
|
||||
#
|
||||
# The Build Options, below, are only used when building the C library.
|
||||
# DO NOT use them when building your application!
|
||||
# Nasty things could happen if you do.
|
||||
#
|
||||
# /Oi is required for Microsoft VC++ to allow "intrinsic" functions to be
|
||||
# defined in this library.
|
||||
#
|
||||
#[BuildOptions]
|
||||
# MSFT:*_*_*_CC_FLAGS = /Oi-
|
||||
|
@@ -19,7 +19,7 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DevShell
|
||||
FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a
|
||||
FILE_GUID = 0a1d4fd8-4704-4501-85eb-93399492cbed
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = DevShell
|
||||
@@ -49,15 +49,3 @@
|
||||
LibWchar
|
||||
LibUefi
|
||||
DevUtility
|
||||
|
||||
################################################################
|
||||
#
|
||||
# The Build Options, below, are only used when building the C library.
|
||||
# DO NOT use them when building your application!
|
||||
# Nasty things could happen if you do.
|
||||
#
|
||||
# /Oi is required for Microsoft VC++ to allow "intrinsic" functions to be
|
||||
# defined in this library.
|
||||
#
|
||||
#[BuildOptions]
|
||||
# MSFT:*_*_*_CC_FLAGS = /Oi-
|
||||
|
@@ -15,7 +15,7 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DevUtility
|
||||
FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a
|
||||
FILE_GUID = d6a9928c-3397-4dd1-818f-c664ba6dcaaf
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = DevUtility
|
||||
@@ -42,15 +42,3 @@
|
||||
LibC
|
||||
LibWchar
|
||||
LibUefi
|
||||
|
||||
################################################################
|
||||
#
|
||||
# The Build Options, below, are only used when building the C library.
|
||||
# DO NOT use them when building your application!
|
||||
# Nasty things could happen if you do.
|
||||
#
|
||||
# /Oi- is required for Microsoft VC++ to allow "intrinsic" functions to be
|
||||
# defined in this library.
|
||||
#
|
||||
#[BuildOptions]
|
||||
# MSFT:*_*_*_CC_FLAGS = /Oi-
|
||||
|
Reference in New Issue
Block a user