Post by Deleted on May 16, 2016 22:00:17 GMT
this:
I think noone yet here got to such a stupidity like posting his/her code. xD But this is what I'm doing right now.)
Kind of "finished" that function. in reality - of course not, there is at least those macros (SEARCH_TREE and INSERT_TREE), which should have been implemented yet. And also - synchronization, as it's seen - that "atomic" update isn't such yet. Still. it's a pleasure to see at this.)
EFI_STATUS EFIAPI InstallProtocolInterface(
IN OUT EFI_HANDLE *pEfiHandle,
IN EFI_GUID *pProtocol,
IN EFI_INTERFACE_TYPE InterfaceType,
IN VOID *pInterface
){
PHANDLE pHandle;
PPROTOCOL pProto;
PPHANDLE ppHandle;
UINTN Noh;
PPROTOCOL_TREE pProtocolNode;
PEFI_GUID pGuid;
EFI_STATUS Status;
if(!pEfiHandle || !pProtocol || InterfaceType != EfiNativeInterface)return EFI_INVALID_PARAMETER;
pProtocolNode = SEARCH_TREE(gpHandleDataBase->pProtocolTreeRoot, pProtocol);
if(!pProtocolNode){
/* Allocate Protocol Node */
Status = AllocatePool(EfiLoaderData, sizeof(PROTOCOL_TREE), &pProtocolNode);
if(Status != EFI_SUCCESS)return Status;
/* Init Protocol Node */
/* Copy Guid */
pGuid = &(pProtocolNode->Guid);
*((UINT64 *)pGuid) = *((UINT64 *)pProtocol);
*((UINT64 *)pGuid+1) = *((UINT64 *)pProtocol+1);
pProtocolNode->NumberOfHandles = 0;
INSERT_TREE(pProtocolNode, pProtocol);
/* Allocate PHANDLE array for the node */
Status = AllocatePool(
EfiLoaderData,
(sizeof(PHANDLE) * gPhandleArrayLength),
&(pProtocolNode->ppHandleArray)
);
/* we don't delete the node even if
* phandle array allocation failed
* - it might be used later
*/
if(Status != EFI_SUCCESS)return Status;
}else if(pProtocolNode->NumberOfHandles == pProtocolNode->PhandleArrayLength){
/* extend the phandle array */
Noh = gPhandleArrayLength; /* trying to really extend the array */
Status = MiExtendPool(pProtocolNode->ppHandleArray, sizeof(PHANDLE), &Noh);
if(!Noh || Status != EFI_SUCCESS){ /* didn't work out, do copying */
Noh = gPhandleArrayLength<<1;
Status = AllocatePool(EfiLoaderData, (sizeof(PHANDLE) * Noh), &ppHandle);
if(Status != EFI_SUCCESS)return Status;
MiCopyMemory(
ppHandle,
pProtocolNode->ppHandleArray,
(sizeof(PHANDLE) * (pProtocolNode->PhandleArrayLength))
);
pProtocolNode->PhandleArrayLength = Noh;
pProtocolNode->ppHandleArray = ppHandle;
}else{ /* the extension succeeded, commit it */
pProtocolNode->PhandleArrayLength += Noh;
}
}
if(!*pEfiHandle){
if(gpHandleDataBase->NumberOfValidHandles == gpHandleDataBase->HandleTableLength)
return EFI_OUT_OF_RESOURCES; /* shit happened, we have not guessed the table capacity right */
/* add new handle */
pHandle = gpHandleDataBase->pHandleTable;
while(pHandle->State == HANDLE_STATE_VALID)pHandle++; /* get the first empty slot */
Status = AllocatePool( /* Allocate protocol array for the fresh handle */
EfiLoaderData,
sizeof(PROTOCOL)* gProtocolArrayLength,
&pProto
);
if(Status != EFI_SUCCESS)return Status; /* out of resources, man */
pHandle->State = HANDLE_STATE_VALID; /* partial init needed here */
pHandle->NumberOfProtocolInterfaces = 0;
pHandle->pProtocolArray = pProto;
}else{
pHandle = (PHANDLE)*pEfiHandle;
if(pHandle->State != HANDLE_STATE_VALID)return EFI_INVALID_PARAMETER;
Noh = pProtocolNode->NumberOfHandles; /* check if the protocol is already installed */
ppHandle = pProtocolNode->ppHandleArray;
while(Noh){
if(*ppHandle == pHandle)return EFI_INVALID_PARAMETER; /* it is, that's not right */
ppHandle++;
Noh--;
}
if(pHandle->NumberOfProtocolInterfaces == pHandle->ProtocolArrayLength){
/* extend the protocol array for the handle */
Noh = gProtocolArrayLength;
Status = MiExtendPool(pHandle->pProtocolArray, sizeof(PROTOCOL), &Noh);
if(!Noh || Status != EFI_SUCCESS){
Noh = gProtocolArrayLength<<1;
Status = AllocatePool(EfiLoaderData, (sizeof(PROTOCOL) * Noh), &pProto);
if(Status != EFI_SUCCESS)return Status;
MiCopyMemory(
pProto,
pHandle->pProtocolArray,
(sizeof(PROTOCOL) * (pHandle->ProtocolArrayLength))
);
pHandle->ProtocolArrayLength = Noh;
pHandle->pProtocolArray = pProto;
}else{
Phandle->ProtocolArrayLength += Noh;
}
}
pProto = (pHandle->pProtocolArray + pHandle->NumberOfProtocolInterfaces);
}
/* do an atomic update of the handle database */
pProto->pGuid = &(pProtocolNode->Guid);
pProto->pInterface = pInterface;
pProto->NumberOfAgents = 0;
pProto->pAgentArray = NULL;
pHandle->NumberOfProtocolInterfaces += 1;
*(pProtocolNode->ppHandleArray + pProtocolNode->NumberOfHandles) = pHandle;
pProtocolNode->NumberOfHandles +=1;
return EFI_SUCCESS;
}
I think noone yet here got to such a stupidity like posting his/her code. xD But this is what I'm doing right now.)
Kind of "finished" that function. in reality - of course not, there is at least those macros (SEARCH_TREE and INSERT_TREE), which should have been implemented yet. And also - synchronization, as it's seen - that "atomic" update isn't such yet. Still. it's a pleasure to see at this.)