示例#1
0
Word
restoreValue(Fragment *F, Word *vals, IRRef ref)
{
  IRIns *ir = IR(ref);
  HeapInfo *hp;
  Closure *cl;
  int j;

  // We only need to treat allocations specially.
  if (ir->o != IR_NEW)
    return vals[ref];

  hp = &F->heap[ir->op2];
  // Store has *not* been sunken, i.e., allocation occurred on-trace
  if (!ir_issunken(ir))
    return vals[ref];

  // Otherwise we need to do the allocation now, possibly recursively
  //
  // TODO: Can we have mutually recursive sunken refs?
  recordEvent(EV_ALLOC, 1 + hp->nfields);
  cl = allocClosure(wordsof(ClosureHeader) + hp->nfields);
  setInfo(cl, (InfoTable*)vals[ir->op1]);
  DBG_PR("(alloc[%lu])", wordsof(ClosureHeader) + hp->nfields);

  for (j = 0; j < hp->nfields; j++)
    cl->payload[j] = restoreValue(F, vals, getHeapInfoField(F, hp, j));

  return (Word)cl;
}
示例#2
0
文件: test-log.c 项目: yygcode/ycc
int main()
{
	if (gl_open("/tmp/tests/common/test-log.log", 1, LOG_DEBUG)) {
		pr_err("LOG_OPEN failed");
		return 1;
	}

	gl_write(LOG_DEBUG, "This is first log, write by %s", "yanyg");
	gl_write(LOG_INFO, "This is first log, write by %s", "yanyg");
	gl_write(LOG_NOTICE, "This is first log, write by %s", "yanyg");
	gl_write(LOG_WARNING, "This is first log, write by %s", "yanyg");
	gl_write(LOG_ERR, "This is first log, write by %s", "yanyg");
	gl_write(LOG_CRIT, "This is first log, write by %s", "yanyg");
	gl_write(LOG_ALERT, "This is first log, write by %s", "yanyg");
	gl_write(LOG_EMERG, "This is first log, write by %s", "yanyg");
	gl_write(10, "This is first log, write by %s", "yanyg");

	struct log_info *log;
	
	log = log_open("/tmp/tests/common/test-yyg.log", 0, LOG_NOTICE);
	if (!log) {
		DBG_PE("log_open failed");
		return 1;
	}

	log_write(log, LOG_INFO, "This is yyg log %d", 1000);
	log_write(log, LOG_NOTICE, "This is yyg log %d", 1000);
	log_write(log, LOG_WARNING, "This is yyg log %d", 1000);

	log_close(log);

	log_write(log, LOG_INFO, "This is yyg log %d", 1000);
	log_write(log, LOG_NOTICE, "This is yyg log %d", 1000);
	log_write(log, LOG_WARNING, "This is yyg log %d", 1000);

	log = log_open("tmp/test/common/test-yyg.log", 1, LOG_WARNING);
	if (!log) {
		DBG_PE("log_open failed");
		return 1;
	}

	log_write(log, LOG_INFO, "This is yyg log %d", 2000);
	log_write(log, LOG_NOTICE, "This is yyg log %d", 2000);
	log_write(log, LOG_WARNING, "This is yyg log %d", 2000);

	log_close(log);

	log_write(log, LOG_INFO, "This is yyg log %d", 2000);
	log_write(log, LOG_NOTICE, "This is yyg log %d", 2000);
	log_write(log, LOG_WARNING, "This is yyg log %d", 2000);

	DBG_PR("success");
	return 0;
}
/**
  Test to see if the Mbr buffer is a valid MBR.

  @param  Mbr         Parent Handle.
  @param  LastLba     Last Lba address on the device.
   
  @retval TRUE        Mbr is a Valid MBR.
  @retval FALSE       Mbr is not a Valid MBR.

**/
BOOLEAN
PartitionValidAddLbaOfs (
  IN  MASTER_BOOT_RECORD      *Mbr,
  IN  EFI_LBA                 LastLba
  )
{
#undef FN
#define FN "PartitionValidMbr"
#define DBG_PartitionValidMbr DL_80 /* DL_DISABLED DL_80 */
#if 0
  UINT32  StartingLBA;
  UINT32  EndingLBA;
  UINT32  NewEndingLBA;
  INTN    Index1;
  INTN    Index2;
#endif
  BOOLEAN MbrValid;
  EFI_LBA AddLbaOfs;
  

#if 0  
  /* (MBR_SIGNATURE + 1) OVMF zeroes out 0x55AB?! */
  if (Mbr->Signature != MBR_SIGNATURE + 1) {
    return FALSE;
  }
#endif

  DBG_X(DBG_PartitionValidMbr, (PrBufxxdr((UINT8 *)&Mbr->BootStrapCode[ADDLBAOFS_SIG_OFS], ADDLBAOFS_SIG_STR_LEN)));
  if (CompareMem(&Mbr->BootStrapCode[ADDLBAOFS_SIG_OFS], ADDLBAOFS_SIG_STR, ADDLBAOFS_SIG_STR_LEN) != 0) {
    return FALSE;
  }
  
  AddLbaOfs = SwapBytes64(*((UINT64 *)((UINT8 *)&Mbr->BootStrapCode[ADDLBAOFS_32_OFS])));
  DBG_PR(DBG_PartitionValidMbr, "AddLbaOfs=%"PRIx64"\n", AddLbaOfs);
  
  MbrValid = TRUE;

  return MbrValid;
}
示例#4
0
int
irEngine(Capability *cap, Fragment *F)
{
  static Inst disp[] = {
#define IRIMPL(name, f, o1, o2)  &&op_##name,
    IRDEF(IRIMPL)
#undef IRIMPL
    &&stop
  };

  
  IRRef ref;
  Thread *T = cap->T;
  Word nphis = F->nphis;
  Word *base = T->base - 1;
  Word szins = F->nins - F->nk;
  Word vals_[szins + nphis];
  Word *phibuf = &vals_[szins]; /* For parallel copy of PHI nodes */
  Word *vals = vals_ - (int)F->nk;
       
  IRIns *pc = F->ir + REF_FIRST;
  IRRef pcref = REF_FIRST;
  IRIns *pcmax = F->ir + F->nins;
  IRIns *pcloop = F->nloop ? F->ir + F->nloop + 1 : pc;
  //int count = 100;

  DBG_PR("*** Executing trace.\n"
         "***   base  = %p\n"
         "***   pc    = %p\n"
         "***   pcmax = %p (%d)\n"
         "***   loop  = %p (%d)\n",
         base, pc, pcmax, (int)(pcmax - pc), pcloop, (int)(pcloop - pc));

  for (ref = F->nk; ref < REF_BIAS; ref++) {
    switch (IR(ref)->o) {
    case IR_KINT:   vals[ref] = (Word)IR(ref)->i; break;
    case IR_KBASEO: vals[ref] = (Word)(T->base + IR(ref)->i); break;
    case IR_KWORD:  vals[ref] = (Word)(F->kwords[IR(ref)->u]); break;
    default:
      LC_ASSERT(0); break;
    }
    DBG_LVL(2, "%d, %" FMT_WordX "\n", ref - REF_BIAS, vals[ref]);
  }
  vals[REF_BASE] = (Word)base;

  goto *disp[pc->o];

# define DISPATCH_NEXT \
  if (irt_type(pc->t) != IRT_VOID && pc->o != IR_PHI) { \
    if (irt_type(pc->t) == IRT_I32) \
      DBG_LVL(2, "         ===> %" FMT_Int "\n", vals[pcref]); \
    else \
      DBG_LVL(2, "         ===> 0x%" FMT_WordX "\n", vals[pcref]); } \
  ++pc; ++pcref; \
  if (LC_UNLIKELY(pc >= pcmax)) { pc = pcloop; pcref = F->nloop + 1; } \
  if (pc->o != IR_NOP) { \
    DBG_LVL(2, "[%d] ", pcref - REF_BIAS); \
    IF_DBG_LVL(2, printIR(F, *pc)); } \
  goto *disp[pc->o]

 op_NOP:
 op_FRAME:
 op_RET:
 op_LOOP:
  DISPATCH_NEXT;

 op_PHI:
  {
    /* PHI nodes represent parallel assignments, so as soon as we
       discover the first PHI node, we perform all assignments in
       parallel. */
    LC_ASSERT(nphis > 0);
    u2 i;
    DBG_LVL(3, "             ( ");
    for (i = 0; i < nphis; i++) {
      DBG_LVL(3, "%d ", irref_int(pc[i].op2));
      phibuf[i] = vals[pc[i].op2];
    }
    DBG_LVL(3, ") --> ( ");
    for (i = 0; i < nphis; i++) {
      DBG_LVL(3, "%d ", irref_int(pc[i].op1));
      vals[pc[i].op1] = phibuf[i];
    }
    DBG_LVL(3, ")  [%d phis]\n", (int)nphis);
    pc += nphis - 1;
    //vals[pc->op1] = vals[pc->op2];
    DISPATCH_NEXT;
  }

 op_LT:
  recordEvent(EV_CMP, 0);
  if (!((WordInt)vals[pc->op1] < (WordInt)vals[pc->op2]))
    goto guard_failed;
  DISPATCH_NEXT;

 op_GE:
  recordEvent(EV_CMP, 0);
  if (!((WordInt)vals[pc->op1] >= (WordInt)vals[pc->op2]))
    goto guard_failed;
  DISPATCH_NEXT;

 op_LE:
  recordEvent(EV_CMP, 0);
  if (!((WordInt)vals[pc->op1] <= (WordInt)vals[pc->op2]))
    goto guard_failed;
  DISPATCH_NEXT;

 op_GT:
  recordEvent(EV_CMP, 0);
  if (!((WordInt)vals[pc->op1] > (WordInt)vals[pc->op2]))
    goto guard_failed;
  DISPATCH_NEXT;

 op_EQ:
  recordEvent(EV_CMP, 0);
  if (!((WordInt)vals[pc->op1] == (WordInt)vals[pc->op2])) {
    goto guard_failed;
  }
  DISPATCH_NEXT;

 op_NE:
  recordEvent(EV_CMP, 0);
  if (!((WordInt)vals[pc->op1] != (WordInt)vals[pc->op2]))
    goto guard_failed;
  DISPATCH_NEXT;

 op_ADD:
  recordEvent(EV_ALU, 0);
  vals[pcref] = vals[pc->op1] + vals[pc->op2];
  DISPATCH_NEXT;

 op_SUB:
  recordEvent(EV_ALU, 0);
  vals[pcref] = vals[pc->op1] - vals[pc->op2];
  DISPATCH_NEXT;

 op_MUL:
  recordEvent(EV_MUL, 0);
  vals[pcref] = (WordInt)vals[pc->op1] * (WordInt)vals[pc->op2];
  DISPATCH_NEXT;

 op_DIV:
  recordEvent(EV_REMDIV, 0);
  if (LC_LIKELY(vals[pc->op2] != 0))
    vals[pcref] = (WordInt)vals[pc->op1] / (WordInt)vals[pc->op2];
  else
    LC_ASSERT(0);
  DISPATCH_NEXT;

 op_REM:
  recordEvent(EV_REMDIV, 0);
  if (LC_LIKELY(vals[pc->op2] != 0))
    vals[pcref] = (WordInt)vals[pc->op1] % (WordInt)vals[pc->op2];
  else
    LC_ASSERT(0);
  DISPATCH_NEXT;

 op_FREF:
  vals[pcref] = (Word)(((Closure*)vals[pc->op1])->payload + (pc->op2 - 1));
  DISPATCH_NEXT;

 op_FLOAD:
  recordEvent(EV_LOAD, 0);
  vals[pcref] = *((Word*)vals[pc->op1]);
  DISPATCH_NEXT;

 op_SLOAD:
  recordEvent(EV_LOAD, 0);
  vals[pcref] = base[pc->op1];
  DISPATCH_NEXT;

 op_ILOAD:
  recordEvent(EV_LOAD, 0);
  vals[pcref] = (Word)getInfo(vals[pc->op1]);
  DISPATCH_NEXT;

 op_NEW:
  if (!ir_issunken(pc)) {
    // do actual allocation on trace
    HeapInfo *hp = &F->heap[pc->op2];
    int j;
    recordEvent(EV_ALLOC, hp->nfields + 1);
    Closure *cl = allocClosure(wordsof(ClosureHeader) + hp->nfields);
    setInfo(cl, (InfoTable*)vals[pc->op1]);
    for (j = 0; j < hp->nfields; j++) {
      cl->payload[j] = vals[getHeapInfoField(F, hp, j)];
    }
    vals[pcref] = (Word)cl;
  } else {
    vals[pcref] = 0;  // to trigger an error if accessed
  }
  DISPATCH_NEXT;

 op_UPDATE:
  {
    recordEvent(EV_UPDATE, 0);
    Closure *oldnode = (Closure *)vals[pc->op1];
    Closure *newnode = (Closure *)base[pc->op2];
    setInfo(oldnode, (InfoTable*)&stg_IND_info);
    oldnode->payload[0] = (Word)newnode;
    DISPATCH_NEXT;
  }

 op_RLOAD:
 op_FSTORE:
 op_RENAME:


 op_BNOT: op_BAND: op_BOR: op_BXOR:
 op_BSHL: op_BSHR: op_BSAR:
 op_BROL: op_BROR:

  // These should never be executed.
 op_BASE:
 op_KINT:
 op_KWORD:
 op_KBASEO:
  LC_ASSERT(0);

 guard_failed:
  DBG_PR("Exiting at %d\n", pcref - REF_BIAS);

  {
    int i;
    SnapShot *snap = 0;
    SnapEntry *se;
    for (i = 0; i < F->nsnap; i++) {
      if (F->snap[i].ref == pcref) {
        snap = &F->snap[i];
        break;
      }
    }
    LC_ASSERT(snap != 0);
    snap->count++;
    se = F->snapmap + snap->mapofs;
    DBG_PR("Snapshot: %d, Snap entries: %d, slots = %d\n",
           i, snap->nent, snap->nslots);
    recordEvent(EV_EXIT, snap->nent);
    for (i = 0; i < snap->nent; i++, se++) {
      BCReg s = snap_slot(*se);
      IRRef r = snap_ref(*se);

      DBG_PR("base[%d] = ", s - 1);
      base[s] = restoreValue(F, vals, r);

      IF_DBG_LVL(1, printSlot(stderr, base + s); fprintf(stderr, "\n"));
      //DBG_PR("0x%" FMT_WordX "\n", base[s]);
    }
    DBG_PR("Base slot: %d\n", se[1]);
    //    se[1] = 
    T->pc = (BCIns *)F->startpc + (int)se[0];
    T->base = base + se[1];
    T->top = base + snap->nslots;
    //printFrame(T->base, T->top);
    return 0;
  }

 stop:
  return 1;
}
/**
  Install child handles if the Handle supports AddLbaOfs format.

  @param[in]  This              Calling context.
  @param[in]  Handle            Parent Handle.
  @param[in]  DiskIo            Parent DiskIo interface.
  @param[in]  DiskIo2           Parent DiskIo2 interface.
  @param[in]  BlockIo           Parent BlockIo interface.
  @param[in]  BlockIo2          Parent BlockIo2 interface.
  @param[in]  DevicePath        Parent Device Path.
   
  @retval EFI_SUCCESS       A child handle was added.
  @retval EFI_MEDIA_CHANGED Media change was detected.
  @retval Others            MBR partition was not found.

**/
EFI_STATUS
PartitionInstallAddLbaOfsChildHandles (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   Handle,
  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,
  IN  EFI_DISK_IO2_PROTOCOL        *DiskIo2,
  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,
  IN  EFI_BLOCK_IO2_PROTOCOL       *BlockIo2,
  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
#undef FN
#define FN "PartitionInstallAddLbaOfsChildHandles"
#define DBG_PartitionInstallAddLbaOfsChildHandles DL_80 /* DL_DISABLED DL_80 */
  EFI_STATUS                Status;
  MASTER_BOOT_RECORD        *Mbr;
  //UINT32                    ExtMbrStartingLba;
  UINTN                     Index;
  HARDDRIVE_DEVICE_PATH     HdDev;
  HARDDRIVE_DEVICE_PATH     ParentHdDev;
  EFI_STATUS                Found;
  UINT32                    PartitionNumber;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL  *LastDevicePathNode;
  UINT32                    BlockSize;
  UINT32                    MediaId;
  EFI_LBA                   LastBlock;
  EFI_LBA                   AddLbaOfs;
  EFI_LBA                   Lba;


  DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "entered\n");

  Found           = EFI_NOT_FOUND;

  BlockSize = BlockIo->Media->BlockSize;
  MediaId   = BlockIo->Media->MediaId;
  LastBlock = BlockIo->Media->LastBlock;
  DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "BlockSize=%"PRIx64" MediaId=%"PRIx64" LastBlock=%"PRIx64"\n", BlockSize, MediaId, LastBlock);

  Mbr = AllocatePool (BlockSize);
  if (Mbr == NULL) {
    return Found;
  }

  for (Lba = 0; Lba < 1; Lba++) {
    Status = DiskIo->ReadDisk(
                     DiskIo,
                     MediaId,
                     Lba * BlockSize,
                     BlockSize,
                     Mbr
                     );
    DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "ReadDisk MediaId=%"PRIx32" Lba*BlockSize=%"PRIx64" %r\n", MediaId, Lba * BlockSize, Status);
    if (!EFI_ERROR(Status)) {
      DBG_X(DBG_PartitionInstallAddLbaOfsChildHandles, (PrBufxxdr(Mbr, BlockSize)));
      if (PartitionValidAddLbaOfs (Mbr, LastBlock)) {
        goto ValidMbr;
      }
    }

#if 0
    Status = DiskIo->ReadDisk(
                     DiskIo,
                     MediaId,
                     (LastBlock - Lba) * BlockSize,
                     BlockSize,
                     Mbr
                     );
    DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "ReadDisk MediaId=%"PRIx32" (LastBlock-Lba)*BlockSize=%"PRIx64" %r\n", MediaId, (LastBlock - Lba) * BlockSize, Status);
    if (!EFI_ERROR(Status)) {
      DBG_X(DBG_PartitionInstallAddLbaOfsChildHandles, (PrBufxxdr(Mbr, BlockSize)));
      if (PartitionValidAddLbaOfs (Mbr, LastBlock)) {
        goto ValidMbr;
      }
    }
#endif
  } /* for */
  goto Done;
ValidMbr:
  DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "ValidMbr\n");
  //
  // We have a valid mbr - add each partition
  //
  //
  // Get starting and ending LBA of the parent block device.
  //
  LastDevicePathNode = NULL;
  ZeroMem (&ParentHdDev, sizeof (ParentHdDev));
  DevicePathNode = DevicePath;
  while (!IsDevicePathEnd (DevicePathNode)) {
    LastDevicePathNode  = DevicePathNode;
    DevicePathNode      = NextDevicePathNode (DevicePathNode);
  }

  if (LastDevicePathNode != NULL) {
    if (DevicePathType (LastDevicePathNode) == MEDIA_DEVICE_PATH &&
        DevicePathSubType (LastDevicePathNode) == MEDIA_HARDDRIVE_DP
        ) {
      CopyMem (&ParentHdDev, LastDevicePathNode, sizeof (ParentHdDev));
    } else {
      LastDevicePathNode = NULL;
    }
  }

  PartitionNumber = 1;

  ZeroMem (&HdDev, sizeof (HdDev));
  HdDev.Header.Type     = MEDIA_DEVICE_PATH;
  HdDev.Header.SubType  = MEDIA_HARDDRIVE_DP; //TBD MEDIA_VENDOR_DP
  SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
  HdDev.MBRType         = MBR_TYPE_PCAT; //TBD
  HdDev.SignatureType   = SIGNATURE_TYPE_GUID + 1; //TBD

  if (LastDevicePathNode == NULL) {
    //
    // This is a MBR, add each partition
    //
    Index = 0;
    /* for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) { */
      AddLbaOfs = SwapBytes64(*((UINT64 *)((UINT8 *)&Mbr->BootStrapCode[ADDLBAOFS_32_OFS])));
      DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "AddLbaOfs=%"PRIx64"\n", AddLbaOfs);
      
      HdDev.PartitionNumber = PartitionNumber ++;
      HdDev.PartitionStart  = AddLbaOfs; /* UNPACK_UINT32 (Mbr->Partition[Index].StartingLBA); */
      HdDev.PartitionSize   = LastBlock + 1 - AddLbaOfs; /* UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA); */
      CopyMem (HdDev.Signature, &(Mbr->UniqueMbrSignature[0]), sizeof (Mbr->UniqueMbrSignature));

      Status = PartitionInstallChildHandle (
                This,
                Handle,
                DiskIo,
                DiskIo2,
                BlockIo,
                BlockIo2,
                DevicePath,
                (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
                HdDev.PartitionStart,
                HdDev.PartitionStart + HdDev.PartitionSize - 1,
                MBR_SIZE,
                (BOOLEAN) (Mbr->Partition[Index].OSIndicator == EFI_PARTITION)
                );
      DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "PartitionInstallChildHandle %r\n", Status);
      if (!EFI_ERROR (Status)) {
        Found = EFI_SUCCESS;
      }
    /* } /* for */
  } else {
#if 1
    //Found = EFI_NOT_FOUND;
    goto Done;
#else
    //
    // It's an extended partition. Follow the extended partition
    // chain to get all the logical drives
    //
    ExtMbrStartingLba = 0;

    do {

      Status = DiskIo->ReadDisk (
                         DiskIo,
                         MediaId,
                         MultU64x32 (ExtMbrStartingLba, BlockSize),
                         BlockSize,
                         Mbr
                         );
      if (EFI_ERROR (Status)) {
        Found = Status;
        goto Done;
      }

      if (UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA) == 0) {
        break;
      }

      if ((Mbr->Partition[0].OSIndicator == EXTENDED_DOS_PARTITION) ||
          (Mbr->Partition[0].OSIndicator == EXTENDED_WINDOWS_PARTITION)) {
        ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA);
        continue;
      }
      HdDev.PartitionNumber = PartitionNumber ++;
      HdDev.PartitionStart  = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA) + ExtMbrStartingLba + ParentHdDev.PartitionStart;
      HdDev.PartitionSize   = UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA);
      if ((HdDev.PartitionStart + HdDev.PartitionSize - 1 >= ParentHdDev.PartitionStart + ParentHdDev.PartitionSize) ||
          (HdDev.PartitionStart <= ParentHdDev.PartitionStart)) {
        break;
      }

      //
      // The signature in EBR(Extended Boot Record) should always be 0.
      //
      *((UINT32 *) &HdDev.Signature[0]) = 0;

      Status = PartitionInstallChildHandle (
                 This,
                 Handle,
                 DiskIo,
                 DiskIo2,
                 BlockIo,
                 BlockIo2,
                 DevicePath,
                 (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
                 HdDev.PartitionStart - ParentHdDev.PartitionStart,
                 HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1,
                 MBR_SIZE,
                 (BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)
                 );
      if (!EFI_ERROR (Status)) {
        Found = EFI_SUCCESS;
      }

      if ((Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION) &&
          (Mbr->Partition[1].OSIndicator != EXTENDED_WINDOWS_PARTITION)
          ) {
        break;
      }

      ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[1].StartingLBA);
      //
      // Don't allow partition to be self referencing
      //
      if (ExtMbrStartingLba == 0) {
        break;
      }
    } while (ExtMbrStartingLba  < ParentHdDev.PartitionSize);
#endif
  }

Done:
  FreePool (Mbr);

  DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "Found=%d\n", Found);
  return Found;
}