⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winceutils.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // Start by figuring a lower bound on the scaling needed to make
    // the upper 96 bits zero.    iHiRes is the index into rgulRes[]
    // of the highest non-zero ULONG.
    // 
    iNewScale =      iHiRes * 32 - 64 - 1;
    if (iNewScale > 0) {

      // Find the MSB.
      //
      ulTmp = rgulRes[iHiRes];
      if (!(ulTmp & 0xFFFF0000)) {
    iNewScale -= 16;
    ulTmp <<= 16;
      }
      if (!(ulTmp & 0xFF000000)) {
    iNewScale -= 8;
    ulTmp <<= 8;
      }
      if (!(ulTmp & 0xF0000000)) {
    iNewScale -= 4;
    ulTmp <<= 4;
      }
      if (!(ulTmp & 0xC0000000)) {
    iNewScale -= 2;
    ulTmp <<= 2;
      }
      if (!(ulTmp & 0x80000000)) {
    iNewScale--;
    ulTmp <<= 1;
      }
    
      // Multiply bit position by log10(2) to figure it's power of 10.
      // We scale the log by 256.  log(2) = .30103, * 256 = 77.     Doing this 
      // with a multiply saves a 96-byte lookup table.    The power returned
      // is <= the power of the number, so we must add one power of 10
      // to make it's integer part zero after dividing by 256.
      // 
      // Note: the result of this multiplication by an approximation of
      // log10(2) have been exhaustively checked to verify it gives the 
      // correct result.  (There were only 95 to check...)
      // 
      iNewScale = ((iNewScale * 77) >> 8) + 1;

      // iNewScale = min scale factor to make high 96 bits zero, 0 - 29.
      // This reduces the scale factor of the result.  If it exceeds the
      // current scale of the result, we'll overflow.
      // 
      if (iNewScale > iScale)
    return -1;
    }
    else
      iNewScale = 0;

    // Make sure we scale by enough to bring the current scale factor
    // into valid range.
    //
    if (iNewScale < iScale - DEC_SCALE_MAX)
      iNewScale = iScale - DEC_SCALE_MAX;

    if (iNewScale != 0) {
      // Scale by the power of 10 given by iNewScale.  Note that this is 
      // NOT guaranteed to bring the number within 96 bits -- it could 
      // be 1 power of 10 short.
      //
      iScale -= iNewScale;
      ulSticky = 0;
      sdlTmp.Hi = 0; // initialize remainder

      for (;;) {

    ulSticky |= sdlTmp.Hi; // record remainder as sticky bit

    if (iNewScale > POWER10_MAX)
      ulPwr = ulTenToNine;
    else
      ulPwr = rgulPower10[iNewScale];

    // Compute first quotient.
    // DivMod64by32 returns quotient in Lo, remainder in Hi.
    //
    sdlTmp.int64 = DivMod64by32(rgulRes[iHiRes], ulPwr);
    rgulRes[iHiRes] = sdlTmp.Lo;
    iCur = iHiRes - 1;

    if (iCur >= 0) {
      // If first quotient was 0, update iHiRes.
      //
      if (sdlTmp.Lo == 0)
        iHiRes--;

      // Compute subsequent quotients.
      //
      do {
        sdlTmp.Lo = rgulRes[iCur];
        sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulPwr);
        rgulRes[iCur] = sdlTmp.Lo;
        iCur--;
      } while (iCur >= 0);

    }

    iNewScale -= POWER10_MAX;
    if (iNewScale > 0)
      continue; // scale some more

    // If we scaled enough, iHiRes would be 2 or less.  If not,
    // divide by 10 more.
    //
    if (iHiRes > 2) {
      iNewScale = 1;
      iScale--;
      continue; // scale by 10
    }

    // Round final result.    See if remainder >= 1/2 of divisor.
    // If remainder == 1/2 divisor, round up if odd or sticky bit set.
    //
    ulPwr >>= 1;  // power of 10 always even
    if ( ulPwr <= sdlTmp.Hi && (ulPwr < sdlTmp.Hi ||
        ((rgulRes[0] & 1) | ulSticky)) ) {
      iCur = -1;
      while (++rgulRes[++iCur] == 0);

      if (iCur > 2) {
        // The rounding caused us to carry beyond 96 bits. 
        // Scale by 10 more.
        //
        iHiRes = iCur;
        ulSticky = 0;  // no sticky bit
        sdlTmp.Hi = 0; //    or remainder
        iNewScale = 1;
        iScale--;
        continue; // scale by 10
      }
    }

    // We may have scaled it more than we planned.    Make sure the scale 
    // factor hasn't gone negative, indicating overflow.
    // 
    if (iScale < 0)
      return -1;

    return iScale;
      } // for(;;)
    }
    return iScale;
}



STDAPI DecAddSub(LPDECIMAL pdecL, LPDECIMAL pdecR, LPDECIMAL pdecRes, char bSign)
{
    ULONG     rgulNum[6];
    ULONG     ulPwr;
    int          iScale;
    int          iHiProd;
    int          iCur;
    SPLIT64   sdlTmp;
    DECIMAL   decRes;
    DECIMAL   decTmp;
    LPDECIMAL pdecTmp;

    bSign ^= (pdecR->sign ^ pdecL->sign) & DECIMAL_NEG;

    if (pdecR->scale == pdecL->scale) {
      // Scale factors are equal, no alignment necessary.
      //
      decRes.signscale = pdecL->signscale;

AlignedAdd:
      if (bSign) {
    // Signs differ - subtract
    //
    decRes.Lo64 = pdecL->Lo64 - pdecR->Lo64;
    decRes.Hi32 = pdecL->Hi32 - pdecR->Hi32;

    // Propagate carry
    //
    if (decRes.Lo64 > pdecL->Lo64) {
      decRes.Hi32--;
      if (decRes.Hi32 >= pdecL->Hi32)
        goto SignFlip;
    }
    else if (decRes.Hi32 > pdecL->Hi32) {
      // Got negative result.  Flip its sign.
      // 
SignFlip:
      decRes.Lo64 = -(LONGLONG)decRes.Lo64;
      decRes.Hi32 = ~decRes.Hi32;
      if (decRes.Lo64 == 0)
        decRes.Hi32++;
      decRes.sign ^= DECIMAL_NEG;
    }

      }
      else {
    // Signs are the same - add
    //
    decRes.Lo64 = pdecL->Lo64 + pdecR->Lo64;
    decRes.Hi32 = pdecL->Hi32 + pdecR->Hi32;

    // Propagate carry
    //
    if (decRes.Lo64 < pdecL->Lo64) {
      decRes.Hi32++;
      if (decRes.Hi32 <= pdecL->Hi32)
        goto AlignedScale;
    }
    else if (decRes.Hi32 < pdecL->Hi32) {
AlignedScale:
      // The addition carried above 96 bits.  Divide the result by 10,
      // dropping the scale factor.
      // 
      if (decRes.scale == 0)
        return DISP_E_OVERFLOW;
      decRes.scale--;

      sdlTmp.Lo = decRes.Hi32;
      sdlTmp.Hi = 1;
      sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
      decRes.Hi32 = sdlTmp.Lo;

      sdlTmp.Lo = decRes.Mid32;
      sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
      decRes.Mid32 = sdlTmp.Lo;

      sdlTmp.Lo = decRes.Lo32;
      sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
      decRes.Lo32 = sdlTmp.Lo;

      // See if we need to round up.
      //
      if (sdlTmp.Hi >= 5 && (sdlTmp.Hi > 5 || (decRes.Lo32 & 1))) {
        if (++decRes.Lo64 == 0)
          decRes.Hi32++;
      }
    }
      }
    }
    else {
      // Scale factors are not equal.  Assume that a larger scale
      // factor (more decimal places) is likely to mean that number
      // is smaller.  Start by guessing that the right operand has
      // the larger scale factor.  The result will have the larger
      // scale factor.
      //
      decRes.scale = pdecR->scale;  // scale factor of "smaller"
      decRes.sign = pdecL->sign;    // but sign of "larger"
      iScale = decRes.scale - pdecL->scale;

      if (iScale < 0) {
    // Guessed scale factor wrong. Swap operands.
    //
    iScale = -iScale;
    decRes.scale = pdecL->scale;
    decRes.sign ^= bSign;
    pdecTmp = pdecR;
    pdecR = pdecL;
    pdecL = pdecTmp;
      }

      // *pdecL will need to be multiplied by 10^iScale so
      // it will have the same scale as *pdecR.     We could be
      // extending it to up to 192 bits of precision.
      //
      if (iScale <= POWER10_MAX) {
    // Scaling won't make it larger than 4 ULONGs
    //
    ulPwr = rgulPower10[iScale];
    decTmp.Lo64 = UInt32x32To64(pdecL->Lo32, ulPwr);
    sdlTmp.int64 = UInt32x32To64(pdecL->Mid32, ulPwr);
    sdlTmp.int64 += decTmp.Mid32;
    decTmp.Mid32 = sdlTmp.Lo;
    decTmp.Hi32 = sdlTmp.Hi;
    sdlTmp.int64 = UInt32x32To64(pdecL->Hi32, ulPwr);
    sdlTmp.int64 += decTmp.Hi32;
    if (sdlTmp.Hi == 0) {
      // Result fits in 96 bits.  Use standard aligned add.
      //
      decTmp.Hi32 = sdlTmp.Lo;
      pdecL = &decTmp;
      goto AlignedAdd;
    }
    rgulNum[0] = decTmp.Lo32;
    rgulNum[1] = decTmp.Mid32;
    rgulNum[2] = sdlTmp.Lo;
    rgulNum[3] = sdlTmp.Hi;
    iHiProd = 3;
      }
      else {
    // Have to scale by a bunch.  Move the number to a buffer
    // where it has room to grow as it's scaled.
    //
    rgulNum[0] = pdecL->Lo32;
    rgulNum[1] = pdecL->Mid32;
    rgulNum[2] = pdecL->Hi32;
    iHiProd = 2;

    // Scan for zeros in the upper words.
    //
    if (rgulNum[2] == 0) {
      iHiProd = 1;
      if (rgulNum[1] == 0) {
        iHiProd = 0;
        if (rgulNum[0] == 0) {
          // Left arg is zero, return right.
          //
          decRes.Lo64 = pdecR->Lo64;
          decRes.Hi32 = pdecR->Hi32;
          decRes.sign ^= bSign;
          goto RetDec;
        }
      }
    }

    // Scaling loop, up to 10^9 at a time.    iHiProd stays updated
    // with index of highest non-zero ULONG.
    //
    for (; iScale > 0; iScale -= POWER10_MAX) {
      if (iScale > POWER10_MAX)
        ulPwr = ulTenToNine;
      else
        ulPwr = rgulPower10[iScale];

      sdlTmp.Hi = 0;
      for (iCur = 0; iCur <= iHiProd; iCur++) {
        sdlTmp.int64 = UInt32x32To64(rgulNum[iCur], ulPwr) + sdlTmp.Hi;
        rgulNum[iCur] = sdlTmp.Lo;
      }

      if (sdlTmp.Hi != 0)
        // We're extending the result by another ULONG.
        rgulNum[++iHiProd] = sdlTmp.Hi;
    }
      }

      // Scaling complete, do the add.  Could be subtract if signs differ.
      //
      sdlTmp.Lo = rgulNum[0];
      sdlTmp.Hi = rgulNum[1];

      if (bSign) {
    // Signs differ, subtract.
    //
    decRes.Lo64 = sdlTmp.int64 - pdecR->Lo64;
    decRes.Hi32 = rgulNum[2] - pdecR->Hi32;

    // Propagate carry
    //
    if (decRes.Lo64 > sdlTmp.int64) {
      decRes.Hi32--;
      if (decRes.Hi32 >= rgulNum[2])
        goto LongSub;
    }
    else if (decRes.Hi32 > rgulNum[2]) {
LongSub:
      // If rgulNum has more than 96 bits of precision, then we need to 
      // carry the subtraction into the higher bits.  If it doesn't, 
      // then we subtracted in the wrong order and have to flip the 
      // sign of the result.
      // 
      if (iHiProd <= 2)
        goto SignFlip;

      iCur = 3;
      while(rgulNum[iCur++]-- == 0);
      if (rgulNum[iHiProd] == 0)
        iHiProd--;
    }
      }
      else {
    // Signs the same, add.
    //
    decRes.Lo64 = sdlTmp.int64 + pdecR->Lo64;
    decRes.Hi32 = rgulNum[2] + pdecR->Hi32;

    // Propagate carry
    //
    if (decRes.Lo64 < sdlTmp.int64) {
      decRes.Hi32++;
      if (decRes.Hi32 <= rgulNum[2])
        goto LongAdd;
    }
    else if (decRes.Hi32 < rgulNum[2]) {
LongAdd:
      // Had a carry above 96 bits.
      //
      iCur = 3;
      do {
        if (iHiProd < iCur) {
          rgulNum[iCur] = 1;
          iHiProd = iCur;
          break;
        }
      }while (++rgulNum[iCur++] == 0);
    }
      }

      if (iHiProd > 2) {
    rgulNum[0] = decRes.Lo32;
    rgulNum[1] = decRes.Mid32;
    rgulNum[2] = decRes.Hi32;
    decRes.scale = ScaleResult(rgulNum, iHiProd, decRes.scale);
    if (decRes.scale == -1)
      return DISP_E_OVERFLOW;

    decRes.Lo32 = rgulNum[0];
    decRes.Mid32 = rgulNum[1];
    decRes.Hi32 = rgulNum[2];
      }
    }

RetDec:
    COPYDEC(*pdecRes, decRes)
    return NOERROR;
}


STDAPI VarDecCmp(LPDECIMAL pdecL, LPDECIMAL pdecR)
{
    ULONG   ulSgnL;
    ULONG   ulSgnR;
    DECIMAL decRes;
  
    // First check signs and whether either are zero.  If both are
    // non-zero and of the same sign, just use subtraction to compare.
    // 
    ulSgnL = pdecL->Lo32 | pdecL->Mid32 | pdecL->Hi32;
    ulSgnR = pdecR->Lo32 | pdecR->Mid32 | pdecR->Hi32;
    if (ulSgnL != 0)
      ulSgnL = (pdecL->sign & DECIMAL_NEG) | 1;

    if (ulSgnR != 0)
      ulSgnR = (pdecR->sign & DECIMAL_NEG) | 1;

    // ulSgnL & ulSgnR have values 1, 0, or 0x81 depending on if the left/right
    // operand is +, 0, or -.
    //
    if (ulSgnL == ulSgnR) {
      if (ulSgnL == 0)      // both are zero
        return VARCMP_EQ; // return equal

      DecAddSub(pdecL, pdecR, &decRes, DECIMAL_NEG);
      if (decRes.Lo64 == 0 && decRes.Hi32 == 0)
        return VARCMP_EQ;
      if (decRes.sign & DECIMAL_NEG)
        return VARCMP_LT;

      return VARCMP_GT;
    }

    // Signs are different.  Used signed byte compares
    //
    if ((char)ulSgnL > (char)ulSgnR)
      return VARCMP_GT;
    return VARCMP_LT;
}


LONG
My_RegOpenKeyExA (
    HKEY hKey,
    LPCSTR lpSubKey,
    DWORD ulOptions,
    REGSAM samDesired,
    PHKEY phkResult
    )
{
    WCHAR wcDest[_MAX_PATH];
    WCHAR *pwcDest = wcDest;

    if(lpSubKey)
    {
    if(-1 == mbstowcs(wcDest, lpSubKey, _MAX_PATH))
        return ERROR_BAD_ARGUMENTS;
    }
    else
        pwcDest = NULL;

    return RegOpenKeyEx (
            hKey,
            pwcDest,
            ulOptions,
            samDesired,
            phkResult);
}



void  _ui64toa (     
        unsigned __int64 val,
        char *buf,
        unsigned int radix)
{

        char *p;                /* pointer to traverse string */
        char *firstdig;         /* pointer to first digit */
        char temp;              /* temp char */
        unsigned digval;        /* value of digit */
 
        p = buf; 
       
        firstdig = p;           /* save pointer to first digit */
        do {
            digval = (unsigned) (val % radix);
            val /= radix;       /* get next digit */

            /* convert to ascii and store */
            if (digval > 9)
                *p++ = (char) (digval - 10 + 'a');  /* a letter */
            else
                *p++ = (char) (digval + '0');       /* a digit */
        } while (val > 0);
 

        /* We now have the digit of the number in the buffer, but in reverse
           order.  Thus we reverse them now. */
        *p-- = '\0';            /* terminate string; p points to last digit */

        do {
            temp = *p;
            *p = *firstdig;
            *firstdig = temp;   /* swap *p and *firstdig */
            --p;
            ++firstdig;         /* advance to next two digits */
        } while (firstdig < p); /* repeat until halfway */
}




DummyMarshal::DummyMarshal(IUnknown *_punkCtrl) : punkCtrl(_punkCtrl), _refCount(1) 
{
}

HRESULT STDMETHODCALLTYPE 
DummyMarshal::QueryInterface(REFIID riid, void** ppv) 
{
   HRESULT hr = E_NOINTERFACE;
   ASSERT(FALSE);
   return hr;
}


ULONG STDMETHODCALLTYPE 
DummyMarshal::AddRef() 
{
    return InterlockedIncrement((LONG *)&_refCount);
}

ULONG STDMETHODCALLTYPE 
DummyMarshal::Release() 
{   
    ASSERT(_refCount != 0xFFFFFFFF);
    ULONG ret = InterlockedDecrement((LONG *)&_refCount); 
    
    if(!ret) 
        delete this; 
    return ret;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -