Secret.cpp
上传用户:zhanglf88
上传日期:2013-11-19
资源大小:6036k
文件大小:46k
源码类别:

金融证券系统

开发平台:

Visual C++

  1. /*
  2. Cross Platform Core Code.
  3. Copyright(R) 2001-2002 Balang Software.
  4. All rights reserved.
  5. Using:
  6. class CDView;
  7. class CDLocalView;
  8. */
  9. #include "StdAfx.h"
  10. #include "../Include/Secret.h"
  11. #include <winioctl.h>
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CDView
  14. CDView::CDView( DWORD key )
  15. {
  16. for( int i=0; i<4; i++ )
  17. {
  18. m_SubKey[i] = LOWORD( key );
  19. key = key>>4;
  20. }
  21. InitTable( );
  22. }
  23. void CDView::Create( BYTE *pSrc, BYTE *pDest, DWORD len )
  24. {
  25. WORD L,R,t;
  26. while( len >=4 )
  27. {
  28. L = *(WORD*)pSrc;
  29. pSrc += 2;
  30. R = *(WORD*)pSrc;
  31. pSrc += 2;
  32. L = ( R+m_SubKey[0] )^L;
  33. R = (L+m_SubKey[1])^R;
  34. t = L;
  35. L = MAKEWORD( HIBYTE(R), LOBYTE(R) );
  36. R = MAKEWORD( HIBYTE(t), LOBYTE(t) );
  37. L = ( R+m_SubKey[2] )^L;
  38. R = (L+m_SubKey[3])^R;
  39. t = L;
  40. L = MAKEWORD( HIBYTE(R), LOBYTE(R) );
  41. R = MAKEWORD( HIBYTE(t), LOBYTE(t) );
  42. L = ( R+m_SubKey[3] )^L;
  43. R = (L+m_SubKey[2])^R;
  44. t = L;
  45. L = MAKEWORD( HIBYTE(R), LOBYTE(R) );
  46. R = MAKEWORD( HIBYTE(t), LOBYTE(t) );
  47. L = ( R+m_SubKey[1] )^L;
  48. R = (L+m_SubKey[0])^R;
  49. t = L;
  50. L = R;
  51. R = t;
  52. *((DWORD*)pDest) = MAKELONG( L, R );
  53. pDest += 4;
  54. len -= 4;
  55. }//while
  56. for( DWORD i=0; i<len; i++ )
  57. *pDest++ = ~(*pSrc++);
  58. }
  59. void CDView::InitTable()
  60. {
  61. for( int i=0;i<256;i++)  
  62. m_awTable[i] = CalcTable(i, DESLOCAL_PRODUCT_STOCKANA, 0 );
  63. }
  64. WORD CDView::CalcTable(WORD dat,WORD genpoly,WORD accum)
  65. {
  66. int i;
  67. dat <<= 8;
  68. for(i=8;i>0;i--)
  69. {
  70. if((dat^accum) & 0x8000) 
  71. accum = (accum << 1) ^ genpoly;
  72.         else 
  73.          accum <<= 1;
  74. dat <<= 1;
  75. }
  76. return(accum);
  77. }
  78. WORD CDView::Update( WORD crc,WORD byte )
  79. {
  80.   return( (crc << 8) ^ m_awTable[ (crc >> 8) ^ byte ] );
  81. }
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CDLocalView
  84. CDLocalView::CDLocalView( )
  85. {
  86. }
  87. void CDLocalView::Create( BYTE *pSrc, BYTE *pDest, DWORD len )
  88. {
  89. CDView des1( DESLOCAL_KEY1 );
  90. CDView des2( DESLOCAL_KEY2 );
  91. CDView des3( DESLOCAL_KEY3 );
  92. CDView des4( DESLOCAL_KEY4 );
  93. CDView des5( DESLOCAL_KEY5 );
  94. CDView des6( DESLOCAL_KEY6 );
  95. CDView des7( DESLOCAL_KEY7 );
  96. CDView des8( DESLOCAL_KEY8 );
  97. ASSERT( len < 0x00FFFFFF );
  98. BYTE * pTemp = new BYTE[len+1];
  99. memset(pTemp, 0, sizeof(pTemp) );
  100. des1.Create( pSrc, pDest, len );
  101. memcpy( pTemp, pDest, len );
  102. des2.Create( pTemp, pDest, len );
  103. memcpy( pTemp, pDest, len );
  104. des3.Create( pTemp, pDest, len );
  105. memcpy( pTemp, pDest, len );
  106. des4.Create( pTemp, pDest, len );
  107. memcpy( pTemp, pDest, len );
  108. des5.Create( pTemp, pDest, len );
  109. memcpy( pTemp, pDest, len );
  110. des6.Create( pTemp, pDest, len );
  111. memcpy( pTemp, pDest, len );
  112. des7.Create( pTemp, pDest, len );
  113. memcpy( pTemp, pDest, len );
  114. des8.Create( pTemp, pDest, len );
  115. delete pTemp;
  116. }
  117. void CDLocalView::Destroy(BYTE *pSrc, BYTE *pDest, DWORD len)
  118. {
  119. CDView des1( DESLOCAL_KEY8 );
  120. CDView des2( DESLOCAL_KEY7 );
  121. CDView des3( DESLOCAL_KEY6 );
  122. CDView des4( DESLOCAL_KEY5 );
  123. CDView des5( DESLOCAL_KEY4 );
  124. CDView des6( DESLOCAL_KEY3 );
  125. CDView des7( DESLOCAL_KEY2 );
  126. CDView des8( DESLOCAL_KEY1 );
  127. ASSERT( len < 0x00FFFFFF );
  128. BYTE * pTemp = new BYTE[len+1];
  129. memset(pTemp, 0, sizeof(pTemp) );
  130. des1.Create( pSrc, pDest, len );
  131. memcpy( pTemp, pDest, len );
  132. des2.Create( pTemp, pDest, len );
  133. memcpy( pTemp, pDest, len );
  134. des3.Create( pTemp, pDest, len );
  135. memcpy( pTemp, pDest, len );
  136. des4.Create( pTemp, pDest, len );
  137. memcpy( pTemp, pDest, len );
  138. des5.Create( pTemp, pDest, len );
  139. memcpy( pTemp, pDest, len );
  140. des6.Create( pTemp, pDest, len );
  141. memcpy( pTemp, pDest, len );
  142. des7.Create( pTemp, pDest, len );
  143. memcpy( pTemp, pDest, len );
  144. des8.Create( pTemp, pDest, len );
  145. delete pTemp;
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. // RSA
  149. class flex_unit // Provides storage allocation and index checking
  150. {
  151.   unsigned * a; // array of units
  152.   unsigned z; // units allocated
  153. public:
  154.   unsigned n; // used units (read-only)
  155.   flex_unit();
  156.   ~flex_unit();
  157.   void clear(); // set n to zero
  158.   unsigned get( unsigned i ) const;     // get ith unsigned
  159.   void set( unsigned i, unsigned x );   // set ith unsigned
  160.   void reserve( unsigned x );           // storage hint
  161.   // Time critical routine
  162.   void fast_mul( flex_unit &x, flex_unit &y, unsigned n );
  163. };
  164. class vlong_value : public flex_unit
  165. {
  166.   public:
  167.   unsigned share; // share count, used by vlong to delay physical copying
  168.   int is_zero() const;
  169.   int test( unsigned i ) const;
  170.   unsigned bits() const;
  171.   int cf( vlong_value& x ) const;
  172.   void shl();
  173.   void shr();
  174.   void shr( unsigned n );
  175.   void add( vlong_value& x );
  176.   void subtract( vlong_value& x );
  177.   void init( unsigned x );
  178.   void copy( vlong_value& x );
  179.   operator unsigned(); // Unsafe conversion to unsigned
  180.   vlong_value();
  181.   void mul( vlong_value& x, vlong_value& y );
  182.   void divide( vlong_value& x, vlong_value& y, vlong_value& rem );
  183. };
  184. unsigned flex_unit::get( unsigned i ) const
  185. {
  186.   if ( i >= n ) return 0;
  187.   return a[i];
  188. }
  189. void flex_unit::clear()
  190. {
  191.    n = 0;
  192. }
  193. flex_unit::flex_unit()
  194. {
  195.   z = 0;
  196.   a = 0;
  197.   n = 0;
  198. }
  199. flex_unit::~flex_unit()
  200. {
  201.   unsigned i=z;
  202.   while (i) { i-=1; a[i] = 0; } // burn
  203.   delete [] a;
  204. }
  205. void flex_unit::reserve( unsigned x )
  206. {
  207.   if (x > z)
  208.   {
  209.     unsigned * na = new unsigned[x];
  210.     for (unsigned i=0;i<n;i+=1) na[i] = a[i];
  211.     delete [] a;
  212.     a = na;
  213.     z = x;
  214.   }
  215. }
  216. void flex_unit::set( unsigned i, unsigned x )
  217. {
  218.   if ( i < n )
  219.   {
  220.     a[i] = x;
  221.     if (x==0) while (n && a[n-1]==0) n-=1; // normalise
  222.   }
  223.   else if ( x )
  224.   {
  225.     reserve(i+1);
  226.     for (unsigned j=n;j<i;j+=1) a[j] = 0;
  227.     a[i] = x;
  228.     n = i+1;
  229.   }
  230. }
  231. // Macros for doing double precision multiply
  232. #define BPU ( 8*sizeof(unsigned) )       // Number of bits in an unsigned
  233. #define lo(x) ( (x) & ((1<<(BPU/2))-1) ) // lower half of unsigned
  234. #define hi(x) ( (x) >> (BPU/2) )         // upper half
  235. #define lh(x) ( (x) << (BPU/2) )         // make upper half
  236. void flex_unit::fast_mul( flex_unit &x, flex_unit &y, unsigned keep )
  237. {
  238.   // *this = (x*y) % (2**keep)
  239.   unsigned i,limit = (keep+BPU-1)/BPU; // size of result in words
  240.   reserve(limit); for (i=0; i<limit; i+=1) a[i] = 0;
  241.   unsigned min = x.n; if (min>limit) min = limit;
  242.   for (i=0; i<min; i+=1)
  243.   {
  244.     unsigned m = x.a[i];
  245.     unsigned c = 0; // carry
  246.     unsigned min = i+y.n; if (min>limit) min = limit;
  247.     for ( unsigned j=i; j<min; j+=1 )
  248.     {
  249.       // This is the critical loop
  250.       // Machine dependent code could help here
  251.       // c:a[j] = a[j] + c + m*y.a[j-i];
  252.       unsigned w, v = a[j], p = y.a[j-i];
  253.       v += c; c = ( v < c );
  254.       w = lo(p)*lo(m); v += w; c += ( v < w );
  255.       w = lo(p)*hi(m); c += hi(w); w = lh(w); v += w; c += ( v < w );
  256.       w = hi(p)*lo(m); c += hi(w); w = lh(w); v += w; c += ( v < w );
  257.       c += hi(p) * hi(m);
  258.       a[j] = v;
  259.     }
  260.     while ( c && j<limit )
  261.     {
  262.       a[j] += c;
  263.       c = a[j] < c;
  264.       j += 1;
  265.     }
  266.   }
  267.   // eliminate unwanted bits
  268.   keep %= BPU; if (keep) a[limit-1] &= (1<<keep)-1;
  269.    // calculate n
  270.   while (limit && a[limit-1]==0) limit-=1;
  271.   n = limit;
  272. };
  273. vlong_value::operator unsigned()
  274. {
  275.   return get(0);
  276. }
  277. int vlong_value::is_zero() const
  278. {
  279.   return n==0;
  280. }
  281. int vlong_value::test( unsigned i ) const
  282. { return ( get(i/BPU) & (1<<(i%BPU)) ) != 0; }
  283. unsigned vlong_value::bits() const
  284. {
  285.   unsigned x = n*BPU;
  286.   while (x && test(x-1)==0) x -= 1;
  287.   return x;
  288. }
  289. int vlong_value::cf( vlong_value& x ) const
  290. {
  291.   if ( n > x.n ) return +1;
  292.   if ( n < x.n ) return -1;
  293.   unsigned i = n;
  294.   while (i)
  295.   {
  296.     i -= 1;
  297.     if ( get(i) > x.get(i) ) return +1;
  298.     if ( get(i) < x.get(i) ) return -1;
  299.   }
  300.   return 0;
  301. }
  302. void vlong_value::shl()
  303. {
  304.   unsigned carry = 0;
  305.   unsigned N = n; // necessary, since n can change
  306.   for (unsigned i=0;i<=N;i+=1)
  307.   {
  308.     unsigned u = get(i);
  309.     set(i,(u<<1)+carry);
  310.     carry = u>>(BPU-1);
  311.   }
  312. }
  313. void vlong_value::shr()
  314. {
  315.   unsigned carry = 0;
  316.   unsigned i=n;
  317.   while (i)
  318.   {
  319.     i -= 1;
  320.     unsigned u = get(i);
  321.     set(i,(u>>1)+carry);
  322.     carry = u<<(BPU-1);
  323.   }
  324. }
  325. void vlong_value::shr( unsigned x )
  326. {
  327.   unsigned delta = x/BPU; x %= BPU;
  328.   for (unsigned i=0;i<n;i+=1)
  329.   {
  330.     unsigned u = get(i+delta);
  331.     if (x)
  332.     {
  333.       u >>= x;
  334.       u += get(i+delta+1) << (BPU-x);
  335.     }
  336.     set(i,u);
  337.   }
  338. }
  339. void vlong_value::add( vlong_value & x )
  340. {
  341.   unsigned carry = 0;
  342.   unsigned max = n; if (max<x.n) max = x.n;
  343.   reserve(max);
  344.   for (unsigned i=0;i<max+1;i+=1)
  345.   {
  346.     unsigned u = get(i);
  347.     u = u + carry; carry = ( u < carry );
  348.     unsigned ux = x.get(i);
  349.     u = u + ux; carry += ( u < ux );
  350.     set(i,u);
  351.   }
  352. }
  353. void vlong_value::subtract( vlong_value & x )
  354. {
  355.   unsigned carry = 0;
  356.   unsigned N = n;
  357.   for (unsigned i=0;i<N;i+=1)
  358.   {
  359.     unsigned ux = x.get(i);
  360.     ux += carry;
  361.     if ( ux >= carry )
  362.     {
  363.       unsigned u = get(i);
  364.       unsigned nu = u - ux;
  365.       carry = nu > u;
  366.       set(i,nu);
  367.     }
  368.   }
  369. }
  370. void vlong_value::init( unsigned x )
  371. {
  372.   clear();
  373.   set(0,x);
  374. }
  375. void vlong_value::copy( vlong_value& x )
  376. {
  377.   clear();
  378.   unsigned i=x.n;
  379.   while (i) { i -= 1; set( i, x.get(i) ); }
  380. }
  381. vlong_value::vlong_value()
  382. {
  383.   share = 0;
  384. }
  385. void vlong_value::mul( vlong_value& x, vlong_value& y )
  386. {
  387.   fast_mul( x, y, x.bits()+y.bits() );
  388. }
  389. void vlong_value::divide( vlong_value& x, vlong_value& y, vlong_value& rem )
  390. {
  391.   init(0);
  392.   rem.copy(x);
  393.   vlong_value m,s;
  394.   m.copy(y);
  395.   s.init(1);
  396.   while ( rem.cf(m) > 0 )
  397.   {
  398.     m.shl();
  399.     s.shl();
  400.   }
  401.   while ( rem.cf(y) >= 0 )
  402.   {
  403.     while ( rem.cf(m) < 0 )
  404.     {
  405.       m.shr();
  406.       s.shr();
  407.     }
  408.     rem.subtract( m );
  409.     add( s );
  410.   }
  411. }
  412. // Implementation of vlong
  413. void vlong::docopy()
  414. {
  415.   if ( value->share )
  416.   {
  417.     value->share -= 1;
  418.     vlong_value * nv = new vlong_value;
  419.     nv->copy(*value);
  420.     value = nv;
  421.   }
  422. }
  423. int vlong::cf( const vlong x ) const
  424. {
  425.   int neg = negative && !value->is_zero();
  426.   if ( neg == (x.negative && !x.value->is_zero()) )
  427.     return value->cf( *x.value );
  428.   else if ( neg ) return -1;
  429.   else return +1;
  430. }
  431. vlong::vlong (unsigned x)
  432. {
  433.   value = new vlong_value;
  434.   negative = 0;
  435.   value->init(x);
  436. }
  437. vlong::vlong ( const vlong& x ) // copy constructor
  438. {
  439.   negative = x.negative;
  440.   value = x.value;
  441.   value->share += 1;
  442. }
  443. vlong::vlong ( const char * s, int len, int bSysStr )
  444. {
  445.   value = new vlong_value;
  446.   negative = 0;
  447.   value->init(0);
  448.   if( bSysStr )
  449.     *this = from_sysstr( s, len );
  450.   else
  451.     *this = from_str( s, len );
  452. }
  453. vlong& vlong::operator =(const vlong& x)
  454. {
  455.   if ( value->share ) value->share -=1; else delete value;
  456.   value = x.value;
  457.   value->share += 1;
  458.   negative = x.negative;
  459.   return *this;
  460. }
  461. vlong vlong::from_str( const char * s, int len )
  462. {
  463. vlong x(0);
  464. int n = 0;
  465. while (n<len)
  466. {
  467. x = x * vlong(256) + vlong((unsigned char)*s);
  468. s += 1;
  469. n += 1;
  470. }
  471. return x;
  472. }
  473. vlong vlong::from_sysstr( const char * s, int len )
  474. {
  475. char szSystem20[SE_LEN_SYSTEMSTR+1] = SE_SYSTEM20_CHAR;
  476. vlong x(0);
  477. int n = 0;
  478. while (n<len)
  479. {
  480. for( int k=0; k<SE_LEN_SYSTEMSTR; k++ )
  481. {
  482. if( szSystem20[k] == *s )
  483. break;
  484. }
  485. if( k == SE_LEN_SYSTEMSTR )
  486. {
  487. TRACE( "vlong::from_sysstr( ... ), s is not sysstr.n" );
  488. // ASSERT( FALSE );
  489. break;
  490. }
  491. x = x * vlong(SE_LEN_SYSTEMSTR) + vlong(k);
  492. s += 1;
  493. n += 1;
  494. }
  495. return x;
  496. }
  497. int vlong::to_str( char * s, int len )
  498. {
  499. char * pbuf = new char[len+1];
  500. if( 0 == pbuf )
  501. return -1;
  502. memset( s, 0, len );
  503. vlong vllocal( *this );
  504. int n = 0;
  505. while( vllocal != vlong(0) && n < len-1 )
  506. {
  507. *(pbuf+n) = vllocal % vlong(256);
  508. vllocal = vllocal/vlong(256);
  509. n ++;
  510. }
  511. for( int i=n-1; i>=0; i-- )
  512. *(s+n-1-i) = *(pbuf+i);
  513. delete [] pbuf;
  514. if( vllocal != vlong(0) )
  515. return -1;
  516. return n;
  517. }
  518. int vlong::to_sysstr( char * s, int len )
  519. {
  520. char szSystem20[SE_LEN_SYSTEMSTR+1] = SE_SYSTEM20_CHAR;
  521. char * pbuf = new char[len+1];
  522. if( 0 == pbuf )
  523. return -1;
  524. memset( s, 0, len );
  525. vlong vllocal( *this );
  526. int n = 0;
  527. while( vllocal != vlong(0) && n < len-1 )
  528. {
  529. *(pbuf+n) = szSystem20[ unsigned(vllocal % vlong(SE_LEN_SYSTEMSTR)) ];
  530. vllocal = vllocal/vlong(SE_LEN_SYSTEMSTR);
  531. n ++;
  532. }
  533. for( int i=n-1; i>=0; i-- )
  534. *(s+n-1-i) = *(pbuf+i);
  535. delete [] pbuf;
  536. if( vllocal != vlong(0) )
  537. return -1;
  538. return n;
  539. }
  540. vlong::~vlong()
  541. {
  542.   if ( value->share ) value->share -=1; else delete value;
  543. }
  544. vlong::operator unsigned () // conversion to unsigned
  545. {
  546.   return *value;
  547. }
  548. vlong& vlong::operator +=(const vlong& x)
  549. {
  550.   if ( negative == x.negative )
  551.   {
  552.     docopy();
  553.     value->add( *x.value );
  554.   }
  555.   else if ( value->cf( *x.value ) >= 0 )
  556.   {
  557.     docopy();
  558.     value->subtract( *x.value );
  559.   }
  560.   else
  561.   {
  562.     vlong tmp = *this;
  563.     *this = x;
  564.     *this += tmp;
  565.   }
  566.   return *this;
  567. }
  568. vlong& vlong::operator -=(const vlong& x)
  569. {
  570.   if ( negative != x.negative )
  571.   {
  572.     docopy();
  573.     value->add( *x.value );
  574.   }
  575.   else if ( value->cf( *x.value ) >= 0 )
  576.   {
  577.     docopy();
  578.     value->subtract( *x.value );
  579.   }
  580.   else
  581.   {
  582.     vlong tmp = *this;
  583.     *this = x;
  584.     *this -= tmp;
  585.     negative = 1 - negative;
  586.   }
  587.   return *this;
  588. }
  589. vlong operator +( const vlong& x, const vlong& y )
  590. {
  591.   vlong result = x;
  592.   result += y;
  593.   return result;
  594. }
  595. vlong operator -( const vlong& x, const vlong& y )
  596. {
  597.   vlong result = x;
  598.   result -= y;
  599.   return result;
  600. }
  601. vlong operator *( const vlong& x, const vlong& y )
  602. {
  603.   vlong result;
  604.   result.value->mul( *x.value, *y.value );
  605.   result.negative = x.negative ^ y.negative;
  606.   return result;
  607. }
  608. vlong operator /( const vlong& x, const vlong& y )
  609. {
  610.   vlong result;
  611.   vlong_value rem;
  612.   result.value->divide( *x.value, *y.value, rem );
  613.   result.negative = x.negative ^ y.negative;
  614.   return result;
  615. }
  616. vlong operator %( const vlong& x, const vlong& y )
  617. {
  618.   vlong result;
  619.   vlong_value divide;
  620.   divide.divide( *x.value, *y.value, *result.value );
  621.   result.negative = x.negative; // not sure about this?
  622.   return result;
  623. }
  624. vlong gcd( const vlong &X, const vlong &Y )
  625. {
  626.   vlong x=X, y=Y;
  627.   while (1)
  628.   {
  629.     if ( y == vlong(0) ) return x;
  630.     x = x % y;
  631.     if ( x == vlong(0) ) return y;
  632.     y = y % x;
  633.   }
  634. }
  635. vlong modinv( const vlong &a, const vlong &m ) // modular inverse
  636. // returns i in range 1..m-1 such that i*a = 1 mod m
  637. // a must be in range 1..m-1
  638. {
  639.   vlong j=1,i=0,b=m,c=a,x,y;
  640.   while ( c != vlong(0) )
  641.   {
  642.     x = b / c;
  643.     y = b - x*c;
  644.     b = c;
  645.     c = y;
  646.     y = j;
  647.     j = i - j*x;
  648.     i = y;
  649.   }
  650.   if ( i < vlong(0) )
  651.     i += m;
  652.   return i;
  653. }
  654. class monty // class for montgomery modular exponentiation
  655. {
  656.   vlong R,R1,m,n1;
  657.   vlong T,k;   // work registers
  658.   unsigned N;  // bits for R
  659.   void mul( vlong &x, const vlong &y );
  660. public:
  661.   vlong exp( const vlong &x, const vlong &e );
  662.   monty( const vlong &M );
  663. };
  664. monty::monty( const vlong &M )
  665. {
  666.   m = M;
  667.   N = 0; R = 1; while ( R < M ) { R += R; N += 1; }
  668.   R1 = modinv( R-m, m );
  669.   n1 = R - modinv( m, R );
  670. }
  671. void monty::mul( vlong &x, const vlong &y )
  672. {
  673.   // T = x*y;
  674.   T.value->fast_mul( *x.value, *y.value, N*2 );
  675.   // k = ( T * n1 ) % R;
  676.   k.value->fast_mul( *T.value, *n1.value, N );
  677.   // x = ( T + k*m ) / R;
  678.   x.value->fast_mul( *k.value, *m.value, N*2 );
  679.   x += T;
  680.   x.value->shr( N );
  681.   if (x>=m) x -= m;
  682. }
  683. vlong monty::exp( const vlong &x, const vlong &e )
  684. {
  685.   vlong result = R-m, t = ( x * R ) % m;
  686.   unsigned bits = e.value->bits();
  687.   unsigned i = 0;
  688.   while (1)
  689.   {
  690.     if ( e.value->test(i) )
  691.       mul( result, t);
  692.     i += 1;
  693.     if ( i == bits ) break;
  694.     mul( t, t );
  695.   }
  696.   return ( result * R1 ) % m;
  697. }
  698. vlong modexp( const vlong & x, const vlong & e, const vlong & m )
  699. {
  700.   monty me(m);
  701.   return me.exp( x,e );
  702. }
  703. ///////////////////////////////////////////////////////////////////////
  704. // class prime_factory
  705. class prime_factory
  706. {
  707.   unsigned np;
  708.   unsigned *pl;
  709.   public:
  710.   prime_factory();
  711.   ~prime_factory();
  712.   vlong find_prime( vlong & start );
  713. };
  714. // prime factory implementation
  715. static int is_probable_prime( const vlong &p )
  716. {
  717.   // Test based on Fermats theorem a**(p-1) = 1 mod p for prime p
  718.   // For 1000 bit numbers this can take quite a while
  719.   const rep = 4;
  720.   const unsigned any[rep] = { 2,3,5,7 };
  721.   for ( unsigned i=0; i<rep; i+=1 )
  722.     if ( modexp( any[i], p-1, p ) != vlong(1) )
  723.       return 0;
  724.   return 1;
  725. }
  726. prime_factory::prime_factory()
  727. {
  728.   np = 0;
  729.   unsigned NP = 200;
  730.   pl = new unsigned[NP];
  731.   // Initialise pl
  732.   unsigned SS = 8*NP; // Rough estimate to fill pl
  733.   char * b = new char[SS+1]; // one extra to stop search
  734.   for (unsigned i=0;i<=SS;i+=1) b[i] = 1;
  735.   unsigned p = 2;
  736.   while (1)
  737.   {
  738.     // skip composites
  739.     while ( b[p] == 0 ) p += 1;
  740.     if ( p == SS ) break;
  741.     pl[np] = p;
  742.     np += 1;
  743.     if ( np == NP ) break;
  744.     // cross off multiples
  745.     unsigned c = p*2;
  746.     while ( c < SS )
  747.     {
  748.       b[c] = 0;
  749.       c += p;
  750.     }
  751.     p += 1;
  752.   }
  753.   delete [] b;
  754. }
  755. prime_factory::~prime_factory()
  756. {
  757.   delete [] pl;
  758. }
  759. vlong prime_factory::find_prime( vlong & start )
  760. {
  761.   unsigned SS = 1000; // should be enough unless we are unlucky
  762.   char * b = new char[SS]; // bitset of candidate primes
  763.   unsigned tested = 0;
  764.   while (1)
  765.   {
  766.     unsigned i;
  767.     for (i=0;i<SS;i+=1)
  768.       b[i] = 1;
  769.     for (i=0;i<np;i+=1)
  770.     {
  771.       unsigned p = pl[i];
  772.       unsigned r = start % vlong(p); // not as fast as it should be - could do with special routine
  773.       if (r) r = p - r;
  774.       // cross off multiples of p
  775.       while ( r < SS )
  776.       {
  777.         b[r] = 0;
  778.         r += p;
  779.       }
  780.     }
  781.     // now test candidates
  782.     for (i=0;i<SS;i+=1)
  783.     {
  784.       if ( b[i] )
  785.       {
  786.         tested += 1;
  787.         if ( is_probable_prime(start) )
  788.           return start;
  789.       }
  790.       start += 1;
  791.     }
  792.   }
  793.   delete [] b;
  794. }
  795. ///////////////////////////////////////////////////////////////////////
  796. // class private_key and public key
  797. void private_key::create( const char * r1, const char * r2 )
  798. {
  799.   // Choose primes
  800.   {
  801.     prime_factory pf;
  802.     p = pf.find_prime( vlong::from_str(r1,strlen(r1)) );
  803.     q = pf.find_prime( vlong::from_str(r2,strlen(r2)) );
  804.     if ( p > q ) { vlong tmp = p; p = q; q = tmp; }
  805.   }
  806.   // Calculate public key
  807.   {
  808.     m = p*q;
  809.     e = 50001; // must be odd since p-1 and q-1 are even
  810.     while ( gcd(p-vlong(1),e) != vlong(1) || gcd(q-vlong(1),e) != vlong(1) ) e += 2;
  811.   }
  812. }
  813. vlong public_key::encrypt( const vlong& plain )
  814. {
  815.   return modexp( plain, e, m );
  816. }
  817. vlong private_key::decrypt( const vlong& cipher )
  818. {
  819.   // Calculate values for performing decryption
  820.   // These could be cached, but the calculation is quite fast
  821.   vlong d = modinv( e, (p-vlong(1))*(q-vlong(1)) );
  822.   vlong u = modinv( p, q );
  823.   vlong dp = d % (p-vlong(1));
  824.   vlong dq = d % (q-vlong(1));
  825.   // Apply chinese remainder theorem
  826.   vlong a = modexp( cipher % p, dp, p );
  827.   vlong b = modexp( cipher % q, dq, q );
  828.   if ( b < a ) b += q;
  829.   return a + p * ( ((b-a)*u) % q );
  830. }
  831. /////////////////////////////////////////////////////////////////////////////
  832. // Disk Serial
  833. #define PRINTING_TO_CONSOLE_ALLOWED 
  834. #include <stdlib.h>
  835. #include <stdio.h>
  836. #include <windows.h>
  837. // Required to ensure correct PhysicalDrive IOCTL structure setup 
  838. #pragma pack(1) 
  839. // Max number of drives assuming primary/secondary, master/slave topology 
  840. #define MAX_IDE_DRIVES 4 
  841. #define IDENTIFY_BUFFER_SIZE 512 
  842. // IOCTL commands 
  843. #define DFP_GET_VERSION 0x00074080 
  844. #define DFP_SEND_DRIVE_COMMAND 0x0007c084 
  845. #define DFP_RECEIVE_DRIVE_DATA 0x0007c088 
  846. #define FILE_DEVICE_SCSI 0x0000001b 
  847. #define IOCTL_SCSI_MINIPORT_IDENTIFY ((FILE_DEVICE_SCSI << 16) + 0x0501) 
  848. #define IOCTL_SCSI_MINIPORT 0x0004D008 // see NTDDSCSI.H for definition 
  849. // GETVERSIONOUTPARAMS contains the data returned from the 
  850. // Get Driver Version function. 
  851. typedef struct _GETVERSIONOUTPARAMS 
  852. BYTE bVersion; // Binary driver version. 
  853. BYTE bRevision; // Binary driver revision. 
  854. BYTE bReserved; // Not used. 
  855. BYTE bIDEDeviceMap; // Bit map of IDE devices. 
  856. DWORD fCapabilities; // Bit mask of driver capabilities. 
  857. DWORD dwReserved[4]; // For future use. 
  858. } GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS; 
  859. // Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS 
  860. #define CAP_IDE_ID_FUNCTION 1 // ATA ID command supported 
  861. #define CAP_IDE_ATAPI_ID 2 // ATAPI ID command supported 
  862. #define CAP_IDE_EXECUTE_SMART_FUNCTION 4 // SMART commannds supported 
  863. // IDE registers 
  864. #if(_WIN32_WINNT < 0x0400)
  865. typedef struct _IDEREGS 
  866. BYTE bFeaturesReg; // Used for specifying SMART "commands". 
  867. BYTE bSectorCountReg; // IDE sector count register 
  868. BYTE bSectorNumberReg; // IDE sector number register 
  869. BYTE bCylLowReg; // IDE low order cylinder value 
  870. BYTE bCylHighReg; // IDE high order cylinder value 
  871. BYTE bDriveHeadReg; // IDE drive/head register 
  872. BYTE bCommandReg; // Actual IDE command. 
  873. BYTE bReserved; // reserved for future use. Must be zero. 
  874. } IDEREGS, *PIDEREGS, *LPIDEREGS; 
  875. #endif // (_WIN32_WINNT < 0x0400)
  876. // SENDCMDINPARAMS contains the input parameters for the 
  877. // Send Command to Drive function.
  878. #if(_WIN32_WINNT < 0x0400)
  879. typedef struct _SENDCMDINPARAMS 
  880. DWORD cBufferSize; // Buffer size in bytes 
  881. IDEREGS irDriveRegs; // Structure with drive register values. 
  882. BYTE bDriveNumber; // Physical drive number to send 
  883. // command to (0,1,2,3). 
  884. BYTE bReserved[3]; // Reserved for future expansion. 
  885. DWORD dwReserved[4]; // For future use. 
  886. BYTE bBuffer[1]; // Input buffer. 
  887. } SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS; 
  888. #endif // (_WIN32_WINNT < 0x0400)
  889. #define IDE_ATAPI_IDENTIFY 0xA1 // Returns ID sector for ATAPI. 
  890. #define IDE_ATA_IDENTIFY 0xEC // Returns ID sector for ATA. 
  891. // Status returned from driver 
  892. #if(_WIN32_WINNT < 0x0400)
  893. typedef struct _DRIVERSTATUS 
  894. BYTE bDriverError; // Error code from driver, or 0 if no error. 
  895. BYTE bIDEStatus; // Contents of IDE Error register. 
  896. // Only valid when bDriverError is SMART_IDE_ERROR. 
  897. BYTE bReserved[2]; // Reserved for future expansion. 
  898. DWORD dwReserved[2]; // Reserved for future expansion. 
  899. } DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS; 
  900. #endif // (_WIN32_WINNT < 0x0400)
  901. // Structure returned by PhysicalDrive IOCTL for several commands 
  902. #if(_WIN32_WINNT < 0x0400)
  903. typedef struct _SENDCMDOUTPARAMS 
  904. DWORD cBufferSize; // Size of bBuffer in bytes 
  905. DRIVERSTATUS DriverStatus; // Driver status structure. 
  906. BYTE bBuffer[1]; // Buffer of arbitrary length in which to store the data read from the
  907.  // drive. 
  908. } SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS; 
  909. #endif // (_WIN32_WINNT < 0x0400)
  910. // The following struct defines the interesting part of the IDENTIFY 
  911. // buffer: 
  912. typedef struct _IDSECTOR 
  913. USHORT wGenConfig; 
  914. USHORT wNumCyls; 
  915. USHORT wReserved; 
  916. USHORT wNumHeads; 
  917. USHORT wBytesPerTrack; 
  918. USHORT wBytesPerSector; 
  919. USHORT wSectorsPerTrack; 
  920. USHORT wVendorUnique[3]; 
  921. CHAR sSerialNumber[20]; 
  922. USHORT wBufferType; 
  923. USHORT wBufferSize; 
  924. USHORT wECCSize; 
  925. CHAR sFirmwareRev[8]; 
  926. CHAR sModelNumber[40]; 
  927. USHORT wMoreVendorUnique; 
  928. USHORT wDoubleWordIO; 
  929. USHORT wCapabilities; 
  930. USHORT wReserved1; 
  931. USHORT wPIOTiming; 
  932. USHORT wDMATiming; 
  933. USHORT wBS; 
  934. USHORT wNumCurrentCyls; 
  935. USHORT wNumCurrentHeads; 
  936. USHORT wNumCurrentSectorsPerTrack; 
  937. ULONG ulCurrentSectorCapacity; 
  938. USHORT wMultSectorStuff; 
  939. ULONG ulTotalAddressableSectors; 
  940. USHORT wSingleWordDMA; 
  941. USHORT wMultiWordDMA; 
  942. BYTE bReserved[128]; 
  943. } IDSECTOR, *PIDSECTOR; 
  944. typedef struct _SRB_IO_CONTROL 
  945. ULONG HeaderLength; 
  946. UCHAR Signature[8]; 
  947. ULONG Timeout; 
  948. ULONG ControlCode; 
  949. ULONG ReturnCode; 
  950. ULONG Length; 
  951. } SRB_IO_CONTROL, *PSRB_IO_CONTROL; 
  952. // Define global buffers. 
  953. BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; 
  954. char *ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex); 
  955. void PrintIdeInfo (int drive, DWORD diskdata [256]); 
  956. BOOL DoIDENTIFY (HANDLE, PSENDCMDINPARAMS, PSENDCMDOUTPARAMS, BYTE, BYTE, 
  957. PDWORD); 
  958. int ReadPhysicalDriveInNT (void) 
  959. int done = FALSE; 
  960. int drive = 0; 
  961. for (drive = 0; drive < MAX_IDE_DRIVES; drive++) 
  962. HANDLE hPhysicalDriveIOCTL = 0; 
  963. // Try to get a handle to PhysicalDrive IOCTL, report failure 
  964. // and exit if can't. 
  965. char driveName [256]; 
  966. sprintf (driveName, "\\.\PhysicalDrive%d", drive); 
  967. // Windows NT, Windows 2000, must have admin rights 
  968. hPhysicalDriveIOCTL = CreateFile (driveName, 
  969. GENERIC_READ | GENERIC_WRITE, 
  970. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 
  971. OPEN_EXISTING, 0, NULL); 
  972. // if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE) 
  973. // printf ("Unable to open physical drive %d, error code: 0x%lXn", 
  974. // drive, GetLastError ()); 
  975. if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE) 
  976. GETVERSIONOUTPARAMS VersionParams; 
  977. DWORD cbBytesReturned = 0; 
  978. // Get the version, etc of PhysicalDrive IOCTL 
  979. memset ((void*) &VersionParams, 0, sizeof(VersionParams)); 
  980. if ( ! DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION, 
  981. NULL, 
  982. 0, 
  983. &VersionParams, 
  984. sizeof(VersionParams), 
  985. &cbBytesReturned, NULL) ) 
  986. // printf ("DFP_GET_VERSION failed for drive %dn", i); 
  987. // continue; 
  988. // If there is a IDE device at number "i" issue commands 
  989. // to the device 
  990. if (VersionParams.bIDEDeviceMap > 0) 
  991. BYTE bIDCmd = 0; // IDE or ATAPI IDENTIFY cmd 
  992. SENDCMDINPARAMS scip; 
  993. //SENDCMDOUTPARAMS OutCmd; 
  994. // Now, get the ID sector for all IDE devices in the sysstem. 
  995. // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command, 
  996. // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command, 
  997. // otherwise use the IDE_ATA_IDENTIFY command 
  998. bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10) ? 
  999. IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY; 
  1000. memset (&scip, 0, sizeof(scip)); 
  1001. memset (IdOutCmd, 0, sizeof(IdOutCmd)); 
  1002. if ( DoIDENTIFY (hPhysicalDriveIOCTL, 
  1003. &scip, 
  1004. (PSENDCMDOUTPARAMS)&IdOutCmd, 
  1005. (BYTE) bIDCmd, 
  1006. (BYTE) drive, 
  1007. &cbBytesReturned)) 
  1008. DWORD diskdata [256]; 
  1009. int ijk = 0; 
  1010. USHORT *pIdSector = (USHORT *) 
  1011. ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer; 
  1012. for (ijk = 0; ijk < 256; ijk++) 
  1013. diskdata [ijk] = pIdSector [ijk]; 
  1014. PrintIdeInfo (drive, diskdata); 
  1015. done = TRUE; 
  1016. CloseHandle (hPhysicalDriveIOCTL); 
  1017. return done; 
  1018. // DoIDENTIFY 
  1019. // FUNCTION: Send an IDENTIFY command to the drive 
  1020. // bDriveNum = 0-3 
  1021. // bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY 
  1022. BOOL DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, 
  1023. PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum, 
  1024. PDWORD lpcbBytesReturned) 
  1025. // Set up data structures for IDENTIFY command. 
  1026. pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE; 
  1027. pSCIP -> irDriveRegs.bFeaturesReg = 0; 
  1028. pSCIP -> irDriveRegs.bSectorCountReg = 1; 
  1029. pSCIP -> irDriveRegs.bSectorNumberReg = 1; 
  1030. pSCIP -> irDriveRegs.bCylLowReg = 0; 
  1031. pSCIP -> irDriveRegs.bCylHighReg = 0; 
  1032. // Compute the drive number. 
  1033. pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4); 
  1034. // The command can either be IDE identify or ATAPI identify. 
  1035. pSCIP -> irDriveRegs.bCommandReg = bIDCmd; 
  1036. pSCIP -> bDriveNumber = bDriveNum; 
  1037. pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE; 
  1038. return ( DeviceIoControl (hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA, 
  1039. (LPVOID) pSCIP, 
  1040. sizeof(SENDCMDINPARAMS) - 1, 
  1041. (LPVOID) pSCOP, 
  1042. sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, 
  1043. lpcbBytesReturned, NULL) ); 
  1044. // ------------------------------------------------- // 
  1045. // WinIo v1.2 // 
  1046. // Direct Hardware Access Under Windows 9x/NT/2000 // 
  1047. // Copyright 1998-2000 Yariv Kaplan // 
  1048. // http://www.internals.com // 
  1049. // ------------------------------------------------- // 
  1050. //#include <windows.h>
  1051. //#include "instdrv.h" 
  1052. BOOL LoadDeviceDriver( const TCHAR * Name, const TCHAR * Path, HANDLE * lphDevice );
  1053. BOOL UnloadDeviceDriver( const TCHAR * Name );
  1054. HANDLE hDriver;
  1055. bool IsNT;
  1056. bool IsWinIoInitialized = false;
  1057. bool IsWinNT()
  1058. {
  1059. OSVERSIONINFO OSVersionInfo;
  1060. OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1061. GetVersionEx(&OSVersionInfo);
  1062. return OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT; 
  1063. bool InitializeWinIo() 
  1064. char szExePath[MAX_PATH]; 
  1065. PSTR pszSlash; 
  1066. IsNT = IsWinNT(); 
  1067. if (IsNT) 
  1068. if (!GetModuleFileName(GetModuleHandle(NULL), szExePath, 
  1069. sizeof(szExePath))) 
  1070. return false; 
  1071. pszSlash = strrchr(szExePath, '\'); 
  1072. if (pszSlash) 
  1073. pszSlash[1] = 0; 
  1074. else 
  1075. return false; 
  1076. strcat(szExePath, "winio.sys"); 
  1077. // UnloadDeviceDriver("WINIO"); 
  1078. // if (!LoadDeviceDriver("WINIO", szExePath, &hDriver)) 
  1079. // return false; 
  1080. IsWinIoInitialized = true; 
  1081. return true; 
  1082. void ShutdownWinIo() 
  1083. // if (IsNT) 
  1084. // UnloadDeviceDriver("WINIO"); 
  1085. // ------------------------------------------------ // 
  1086. // Port32 v3.0 // 
  1087. // Direct Port Access Under Windows 9x/NT/2000 // 
  1088. // Copyright 1998-2000 Yariv Kaplan // 
  1089. // http://www.internals.com // 
  1090. // ------------------------------------------------ // 
  1091. //#include <windows.h>
  1092. #include <winioctl.h>
  1093. //#include "diskid32.h" 
  1094. //#include "general.h" 
  1095. // These are our ring 0 functions responsible for tinkering with the hardware ports. 
  1096. // They have a similar privilege to a Windows VxD and are therefore free to re therefore free to access 
  1097. // protected system resources (such as the page tables) and even place calls to 
  1098. // exported VxD services. 
  1099. __declspec(naked) void Ring0GetPortVal() 
  1100. _asm 
  1101. Cmp CL, 1 
  1102. Je ByteVal 
  1103. Cmp CL, 2 
  1104. Je WordVal 
  1105. Cmp CL, 4 
  1106. Je DWordVal 
  1107. ByteVal: 
  1108. In AL, DX 
  1109. Mov [EBX], AL 
  1110. Retf 
  1111. WordVal: 
  1112. In AX, DX 
  1113. Mov [EBX], AX 
  1114. Retf 
  1115. DWordVal: 
  1116. In EAX, DX 
  1117. Mov [EBX], EAX 
  1118. Retf 
  1119. __declspec(naked) void Ring0SetPortVal() 
  1120. _asm 
  1121. Cmp CL, 1 
  1122. Je ByteVal 
  1123. Cmp CL, 2 
  1124. Je WordVal 
  1125. Cmp CL, 4 
  1126. Cmp CL, 4 
  1127. Je DWordVal 
  1128. ByteVal: 
  1129. Mov AL, [EBX] 
  1130. Out DX, AL 
  1131. Retf 
  1132. WordVal: 
  1133. Mov AX, [EBX] 
  1134. Out DX, AX 
  1135. Retf 
  1136. DWordVal: 
  1137. Mov EAX, [EBX] 
  1138. Out DX, EAX 
  1139. Retf 
  1140. // This function makes it possible to call ring 0 code from a ring 3 
  1141. // application. 
  1142. bool CallRing0(PVOID pvRing0FuncAddr, WORD wPortAddr, PDWORD pdwPortVal, BYTE 
  1143. bSize) 
  1144. struct GDT_DESCRIPTOR *pGDTDescriptor; 
  1145. struct GDTR gdtr; 
  1146. WORD CallgateAddr[3]; 
  1147. WORD wGDTIndex = 1; 
  1148. _asm Sgdt [gdtr] 
  1149. // Skip the null descriptor 
  1150. pGDTDescriptor = (struct GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8); 
  1151. // Search for a free GDT descriptor 
  1152. for (wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++) 
  1153. if (pGDTDescriptor->Type == 0 && 
  1154. pGDTDescriptor->System == 0 && 
  1155. pGDTDescriptor->DPL == 0 && 
  1156. pGDTDescriptor->Present == 0) 
  1157. // Found one ! 
  1158. // Now we need to transform this descriptor into a callgate. 
  1159. // Note that we're using selector 0x28 since it corresponds 
  1160. // to a ring 0 segment which spans the entire linear address 
  1161. // space of the processor (0-4GB). 
  1162. struct CALLGATE_DESCRIPTOR *pCallgate; 
  1163. pCallgate = (struct CALLGATE_DESCRIPTOR *) pGDTDescriptor; 
  1164. pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr); 
  1165. pCallgate->Selector = 0x28; 
  1166. pCallgate->ParamCount = 0; 
  1167. pCallgate->Unused = 0; 
  1168. pCallgate->Type = 0xc; 
  1169. pCallgate->System = 0; 
  1170. pCallgate->DPL = 3; 
  1171. pCallgate->DPL = 3; 
  1172. pCallgate->Present = 1; 
  1173. pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr); 
  1174. // Prepare the far call parameters 
  1175. CallgateAddr[0] = 0x0; 
  1176. CallgateAddr[1] = 0x0; 
  1177. CallgateAddr[2] = (wGDTIndex << 3) | 3; 
  1178. // Please fasten your seat belts! 
  1179. // We're about to make a hyperspace jump into RING 0. 
  1180. _asm Mov DX, [wPortAddr] 
  1181. _asm Mov EBX, [pdwPortVal] 
  1182. _asm Mov CL, [bSize] 
  1183. _asm Call FWORD PTR [CallgateAddr] 
  1184. // We have made it ! 
  1185. // Now free the GDT descriptor 
  1186. memset(pGDTDescriptor, 0, 8); 
  1187. // Our journey was successful. Seeya. 
  1188. return true; 
  1189. // Advance to the next GDT descriptor 
  1190. pGDTDescriptor++; 
  1191. // Whoops, the GDT is full 
  1192. return false; 
  1193. bool GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize) 
  1194. bool Result; 
  1195. DWORD dwBytesReturned; 
  1196. struct tagPort32Struct Port32Struct; 
  1197. if (IsNT) 
  1198. if (!IsWinIoInitialized) 
  1199. return false; 
  1200. Port32Struct.wPortAddr = wPortAddr; 
  1201. Port32Struct.bSize = bSize; 
  1202. if (!DeviceIoControl(hDriver, IOCTL_WINIO_READPORT, &Port32Struct, 
  1203. sizeof(struct tagPort32Struct), &Port32Struct, 
  1204. sizeof(struct tagPort32Struct), 
  1205. &dwBytesReturned, NULL)) 
  1206. return false; 
  1207. else 
  1208. *pdwPortVal = Port32Struct.dwPortVal; 
  1209. else 
  1210. Result = CallRing0((PVOID)Ring0GetPortVal, wPortAddr, pdwPortVal, bSize); 
  1211. if (Result == false) 
  1212. return false; 
  1213. return true; 
  1214. bool SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize) 
  1215. DWORD dwBytesReturned; 
  1216. struct tagPort32Struct Port32Struct; 
  1217. if (IsNT) 
  1218. if (!IsWinIoInitialized) 
  1219. return false; 
  1220. Port32Struct.wPortAddr = wPortAddr; 
  1221. Port32Struct.dwPortVal = dwPortVal; 
  1222. Port32Struct.bSize = bSize; 
  1223. if (!DeviceIoControl(hDriver, IOCTL_WINIO_WRITEPORT, &Port32Struct, 
  1224. sizeof(struct tagPort32Struct), NULL, 0, 
  1225. &dwBytesReturned, NULL)) 
  1226. return false; 
  1227. else 
  1228. return CallRing0((PVOID)Ring0SetPortVal, wPortAddr, &dwPortVal, bSize); 
  1229. return true; 
  1230. int ReadDrivePortsInWin9X (void) 
  1231. int done = FALSE; 
  1232. int drive = 0; 
  1233. InitializeWinIo (); 
  1234. // Get IDE Drive info from the hardware ports 
  1235. // loop thru all possible drives 
  1236. for (drive = 0; drive < 8; drive++) 
  1237. DWORD diskdata [256]; 
  1238. WORD baseAddress = 0; // Base address of drive controller 
  1239. DWORD portValue = 0; 
  1240. int waitLoop = 0; 
  1241. int index = 0; 
  1242. switch (drive / 2) 
  1243. case 0: baseAddress = 0x1f0; break; 
  1244. case 1: baseAddress = 0x170; break; 
  1245. case 2: baseAddress = 0x1e8; break; 
  1246. case 3: baseAddress = 0x168; break; 
  1247. // Wait for controller not busy 
  1248. waitLoop = 100000; 
  1249. while (--waitLoop > 0) 
  1250. GetPortVal ((WORD) (baseAddress + 7), &portValue, (BYTE) 1); 
  1251. // drive is ready 
  1252. if ((portValue & 0x40) == 0x40) break; 
  1253. // previous drive command ended in error 
  1254. if ((portValue & 0x01) == 0x01) break; 
  1255. if (waitLoop < 1) continue; 
  1256. if (waitLoop < 1) continue; 
  1257. // Set Master or Slave drive 
  1258. if ((drive % 2) == 0) 
  1259. SetPortVal ((WORD) (baseAddress + 6), 0xA0, 1); 
  1260. else 
  1261. SetPortVal ((WORD) (baseAddress + 6), 0xB0, 1); 
  1262. // Get drive info data 
  1263. SetPortVal ((WORD) (baseAddress + 7), 0xEC, 1); 
  1264. // Wait for data ready 
  1265. waitLoop = 100000; 
  1266. while (--waitLoop > 0) 
  1267. GetPortVal ((WORD) (baseAddress + 7), &portValue, 1); 
  1268. // see if the drive is ready and has it's info ready for us 
  1269. if ((portValue & 0x48) == 0x48) break; 
  1270. // see if there is a drive error 
  1271. if ((portValue & 0x01) == 0x01) break; 
  1272. // check for time out or other error 
  1273. if (waitLoop < 1 || portValue & 0x01) continue; 
  1274. // read drive id information 
  1275. for (index = 0; index < 256; index++) 
  1276. diskdata [index] = 0; // init the space 
  1277. GetPortVal (baseAddress, &(diskdata [index]), 2); 
  1278. PrintIdeInfo (drive, diskdata); 
  1279. done = TRUE; 
  1280. ShutdownWinIo (); 
  1281. return done; 
  1282. #define SENDIDLENGTH sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE 
  1283. int ReadIdeDriveAsScsiDriveInNT (void) 
  1284. int done = FALSE; 
  1285. int controller = 0; 
  1286. for (controller = 0; controller < 2; controller++) 
  1287. HANDLE hScsiDriveIOCTL = 0; 
  1288. char driveName [256]; 
  1289. // Try to get a handle to PhysicalDrive IOCTL, report failure 
  1290. // and exit if can't. 
  1291. sprintf (driveName, "\\.\Scsi%d:", controller); 
  1292. // Windows NT, Windows 2000, any rights should do 
  1293. hScsiDriveIOCTL = CreateFile (driveName, 
  1294. GENERIC_READ | GENERIC_WRITE, 
  1295. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 
  1296. OPEN_EXISTING, 0, NULL); 
  1297. // if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE) 
  1298. // printf ("Unable to open SCSI controller %d, error code: 0x%lXn", 
  1299. // controller, GetLastError ()); 
  1300. if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE) 
  1301. int drive = 0; 
  1302. for (drive = 0; drive < 2; drive++) 
  1303. char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH]; 
  1304. SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer; 
  1305. SENDCMDINPARAMS *pin = 
  1306. (SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL)); 
  1307. DWORD dummy; 
  1308. memset (buffer, 0, sizeof (buffer)); 
  1309. p -> HeaderLength = sizeof (SRB_IO_CONTROL); 
  1310. p -> Timeout = 10000; 
  1311. p -> Length = SENDIDLENGTH; 
  1312. p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY; 
  1313. strncpy ((char *) p -> Signature, "SCSIDISK", 8); 
  1314. pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY; 
  1315. pin -> bDriveNumber = drive; 
  1316. if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT, 
  1317. buffer, 
  1318. sizeof (SRB_IO_CONTROL) + 
  1319. sizeof (SENDCMDINPARAMS) - 1, 
  1320. buffer, 
  1321. sizeof (SRB_IO_CONTROL) + SENDIDLENGTH, 
  1322. &dummy, NULL)) 
  1323. SENDCMDOUTPARAMS *pOut = 
  1324. (SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL)); 
  1325. IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer); 
  1326. if (pId -> sModelNumber [0]) 
  1327. DWORD diskdata [256]; 
  1328. int ijk = 0; 
  1329. USHORT *pIdSector = (USHORT *) pId; 
  1330. for (ijk = 0; ijk < 256; ijk++) 
  1331. diskdata [ijk] = pIdSector [ijk]; 
  1332. PrintIdeInfo (controller * 2 + drive, diskdata); 
  1333. done = TRUE; 
  1334. CloseHandle (hScsiDriveIOCTL); 
  1335. return done; 
  1336. char HardDriveSerialNumber [1024]; 
  1337. void PrintIdeInfo (int drive, DWORD diskdata [256]) 
  1338. // copy the hard driver serial number to the buffer 
  1339. strcpy (HardDriveSerialNumber, ConvertToString (diskdata, 10, 19)); 
  1340. #ifdef PRINTING_TO_CONSOLE_ALLOWED 
  1341. switch (drive / 2) 
  1342. case 0: printf ("nPrimary Controller - "); 
  1343. break; 
  1344. case 1: printf ("nSecondary Controller - "); 
  1345. break; 
  1346. case 2: printf ("nTertiary Controller - "); 
  1347. break; 
  1348. case 3: printf ("nQuaternary Controller - "); 
  1349. break; 
  1350. switch (drive % 2) 
  1351. case 0: printf ("Master drivenn"); 
  1352. break; 
  1353. case 1: printf ("Slave drivenn"); 
  1354. break; 
  1355. printf ("Drive Model Number________________: %sn", 
  1356. ConvertToString (diskdata, 27, 46)); 
  1357. printf ("Drive Serial Number_______________: %sn", 
  1358. ConvertToString (diskdata, 10, 19)); 
  1359. printf ("Drive Controller Revision Number__: %sn", 
  1360. ConvertToString (diskdata, 23, 26)); 
  1361. printf ("Controller Buffer Size on Drive___: %u bytesn", 
  1362. diskdata [21] * 512); 
  1363. printf ("Drive Type________________________: "); 
  1364. if (diskdata [0] & 0x0080) 
  1365. printf ("Removablen"); 
  1366. else if (diskdata [0] & 0x0040) 
  1367. printf ("Fixedn"); 
  1368. else printf ("Unknownn"); 
  1369. printf ("Physical Geometry: " 
  1370. "%u Cylinders %u Heads %u Sectors per trackn", 
  1371. diskdata [1], diskdata [3], diskdata [6]); 
  1372. #else // PRINTING_TO_CONSOLE_ALLOWED 
  1373. // nothing to do 
  1374. #endif // PRINTING_TO_CONSOLE_ALLOWED 
  1375. char *ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex) 
  1376. static char string [1024]; 
  1377. int index = 0; 
  1378. int position = 0; 
  1379. // each integer has two characters stored in it backwards 
  1380. for (index = firstIndex; index <= lastIndex; index++) 
  1381. // get high byte for 1st character 
  1382. string [position] = (char) (diskdata [index] / 256); 
  1383. position++; 
  1384. // get low byte for 2nd character 
  1385. string [position] = (char) (diskdata [index] % 256); 
  1386. position++; 
  1387. // end the string 
  1388. string [position] = ''; 
  1389. // cut off the trailing blanks 
  1390. for (index = position - 1; index > 0 && ' ' == string [index]; index--) 
  1391. string [index] = ''; 
  1392. return string; 
  1393. long getHardDriveComputerID () 
  1394. int done = FALSE; 
  1395. //char string [1024]; 
  1396. __int64 id = 0; 
  1397. strcpy (HardDriveSerialNumber, ""); 
  1398. // this works under WinNT4 or Win2K if you have admin rights 
  1399. done = ReadPhysicalDriveInNT (); 
  1400. if ( ! done) done = ReadIdeDriveAsScsiDriveInNT (); 
  1401. // this works under Win9X and calls WINIO.DLL 
  1402. if ( ! done) done = ReadDrivePortsInWin9X (); 
  1403. if (done) 
  1404. char *p = HardDriveSerialNumber; 
  1405. //WriteConstantString ("HardDriveSerialNumber", HardDriveSerialNumber); 
  1406. // ignore first 5 characters from western digital hard drives if 
  1407. // the first four characters are WD-W 
  1408. if ( ! strncmp (HardDriveSerialNumber, "WD-W", 4)) p += 5; 
  1409. for ( ; p && *p; p++) 
  1410. if ('-' == *p) continue; 
  1411. id *= 10; 
  1412. switch (*p) 
  1413. case '0': id += 0; break; 
  1414. case '1': id += 1; break; 
  1415. case '2': id += 2; break; 
  1416. case '3': id += 3; break; 
  1417. case '4': id += 4; break; 
  1418. case '5': id += 5; break; 
  1419. case '6': id += 6; break; 
  1420. case '7': id += 7; break; 
  1421. case '8': id += 8; break; 
  1422. case '9': id += 9; break; 
  1423. case 'a': case 'A': id += 10; break; 
  1424. case 'b': case 'B': id += 11; break; 
  1425. case 'c': case 'C': id += 12; break; 
  1426. case 'd': case 'D': id += 13; break; 
  1427. case 'e': case 'E': id += 14; break; 
  1428. case 'f': case 'F': id += 15; break; 
  1429. case 'g': case 'G': id += 16; break; 
  1430. case 'h': case 'H': id += 17; break; 
  1431. case 'i': case 'I': id += 18; break; 
  1432. case 'j': case 'J': id += 19; break; 
  1433. case 'k': case 'K': id += 20; break; 
  1434. case 'l': case 'L': id += 21; break; 
  1435. case 'm': case 'M': id += 22; break; 
  1436. case 'n': case 'N': id += 23; break; 
  1437. case 'o': case 'O': id += 24; break; 
  1438. case 'p': case 'P': id += 25; break; 
  1439. case 'q': case 'Q': id += 26; break; 
  1440. case 'r': case 'R': id += 27; break; 
  1441. case 's': case 'S': id += 28; break; 
  1442. case 't': case 'T': id += 29; break; 
  1443. case 'u': case 'U': id += 30; break; 
  1444. case 'v': case 'V': id += 31; break; 
  1445. case 'w': case 'W': id += 32; break; 
  1446. case 'x': case 'X': id += 33; break; 
  1447. case 'y': case 'Y': id += 34; break; 
  1448. case 'z': case 'Z': id += 35; break; 
  1449. // make sure no bigger than 16^7 
  1450. if (id > 268435455) id %= 268435456; 
  1451. #ifdef PRINTING_TO_CONSOLE_ALLOWED 
  1452. printf ("nComputer ID_______________________: %dn", id); 
  1453. #endif 
  1454. return (long) id; 
  1455. /////////////////////////////////////////////////////////////////////////////
  1456. // CSView
  1457. //#ifndef _AFX_ENABLE_INLINES
  1458. #define _SECRET_INLINE
  1459. #include "Secret.inl"
  1460. #undef _SECRET_INLINE
  1461. //#endif
  1462. CSView::CSView( )
  1463. {
  1464. m_tmExp = 0;
  1465. m_tmIns = 0;
  1466. m_nMaxEvaDays = 0;
  1467. memset( m_mStd, 0, sizeof(m_mStd) );
  1468. memset( m_eStd, 0, sizeof(m_eStd) );
  1469. m_mStdlen = -1;
  1470. m_eStdlen = -1;
  1471. memset( m_mProf, 0, sizeof(m_mProf) );
  1472. memset( m_eProf, 0, sizeof(m_eProf) );
  1473. m_mProflen = -1;
  1474. m_eProflen = -1;
  1475. }
  1476. CSView::~CSView( )
  1477. {
  1478. }
  1479. #define SF_MAX_SECRETFILE_LENGTH 0x00080000 
  1480. #define SF_SECRETMAGIC_LENGTH 6
  1481. char szSViewFileMagic[] = "MGCSCF";
  1482. DWORD dwSViewFileVersion = 0x20000000;
  1483. BOOL CSView::Load( LPCTSTR lpszFileName )
  1484. {
  1485. if( NULL == lpszFileName || strlen(lpszFileName) <= 0 )
  1486. return FALSE;
  1487. CFile file;
  1488. try
  1489. {
  1490. if( file.Open( lpszFileName, CFile::modeRead | CFile::shareDenyWrite) )
  1491. {
  1492. DWORD dwLen = (DWORD)file.GetLength();
  1493. if( 0 == dwLen || dwLen > SF_MAX_SECRETFILE_LENGTH )
  1494. {
  1495. file.Close();
  1496. return FALSE;
  1497. }
  1498. BYTE *lpSrc = new BYTE[dwLen];
  1499. BYTE *lpDest = new BYTE[dwLen];
  1500. if( !(lpSrc && lpDest && dwLen == file.Read( lpSrc, dwLen )) )
  1501. {
  1502. if( lpSrc ) delete [] lpSrc;
  1503. if( lpDest ) delete [] lpDest;
  1504. file.Close();
  1505. return FALSE;
  1506. }
  1507. file.Close();
  1508. CDLocalView des;
  1509. des.Destroy( lpSrc, lpDest, dwLen );
  1510. CMemFile memfile( lpDest, dwLen );
  1511. CArchive ar( &memfile, CArchive::load );
  1512. TCHAR buffer[SF_SECRETMAGIC_LENGTH+1];
  1513. memset( buffer, 0, sizeof(buffer) );
  1514. ar.ReadString( buffer, SF_SECRETMAGIC_LENGTH );
  1515. if( 0 != strncmp( szSViewFileMagic, buffer, SF_SECRETMAGIC_LENGTH ) )
  1516. {
  1517. ar.Close();
  1518. memfile.Close();
  1519. delete [] lpSrc;
  1520. delete [] lpDest;
  1521. return FALSE;
  1522. }
  1523. Serialize( ar );
  1524. ar.Close();
  1525. memfile.Close();
  1526. delete [] lpSrc;
  1527. delete [] lpDest;
  1528. return TRUE;
  1529. }
  1530. }
  1531. catch ( CException* e )
  1532. {
  1533. e->Delete();
  1534. }
  1535. return FALSE;
  1536. }
  1537. BOOL CSView::Store( LPCTSTR lpszFileName )
  1538. {
  1539. if( NULL == lpszFileName || strlen(lpszFileName) <= 0 )
  1540. return FALSE;
  1541. CFile file;
  1542. try
  1543. {
  1544. CMemFile memfile( 4098 );
  1545. CArchive ar( &memfile, CArchive::store );
  1546. ar.WriteString( szSViewFileMagic );
  1547. Serialize( ar );
  1548. ar.Close();
  1549. DWORD dwLen = (DWORD)memfile.GetLength();
  1550. if( 0 == dwLen || dwLen > SF_MAX_SECRETFILE_LENGTH )
  1551. {
  1552. memfile.Close();
  1553. return FALSE;
  1554. }
  1555. BYTE *lpSrc = new BYTE[dwLen];
  1556. BYTE *lpDest = new BYTE[dwLen];
  1557. memfile.SeekToBegin();
  1558. if( !(lpSrc && lpDest && dwLen == memfile.Read( lpSrc, dwLen )) )
  1559. {
  1560. if( lpSrc ) delete [] lpSrc;
  1561. if( lpDest ) delete [] lpDest;
  1562. memfile.Close();
  1563. return FALSE;
  1564. }
  1565. memfile.Close();
  1566. CDLocalView des;
  1567. des.Create( lpSrc, lpDest, dwLen );
  1568. if( file.Open( lpszFileName, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite) )
  1569. {
  1570. file.Write( lpDest, dwLen );
  1571. file.Close();
  1572. delete [] lpSrc;
  1573. delete [] lpDest;
  1574. return TRUE;
  1575. }
  1576. delete [] lpSrc;
  1577. delete [] lpDest;
  1578. }
  1579. catch ( CException* e )
  1580. {
  1581. e->Delete();
  1582. }
  1583. return FALSE;
  1584. }
  1585. void CSView::Serialize( CArchive &ar )
  1586. {
  1587. if( ar.IsStoring() )
  1588. {
  1589. ar << dwSViewFileVersion;
  1590. ar << m_strU;
  1591. ar << m_strR;
  1592. ar << m_mStdlen;
  1593. ar << m_eStdlen;
  1594. ar.Write( m_mStd, sizeof(m_mStd) );
  1595. ar.Write( m_eStd, sizeof(m_eStd) );
  1596. ar << m_mProflen;
  1597. ar << m_eProflen;
  1598. ar.Write( m_mProf, sizeof(m_mProf) );
  1599. ar.Write( m_eProf, sizeof(m_eProf) );
  1600. ar << m_tmExp.GetTime();
  1601. ar << m_tmIns.GetTime();
  1602. ar << m_nMaxEvaDays;
  1603. ar << m_strAR;
  1604. ar << m_strNSAText;
  1605. }
  1606. else
  1607. {
  1608. ar >> m_dwFileVersion;
  1609. if( m_dwFileVersion > dwSViewFileVersion )
  1610. return;
  1611. ar >> m_strU;
  1612. ar >> m_strR;
  1613. ar >> m_mStdlen;
  1614. ar >> m_eStdlen;
  1615. ar.Read( m_mStd, sizeof(m_mStd) );
  1616. ar.Read( m_eStd, sizeof(m_eStd) );
  1617. ar >> m_mProflen;
  1618. ar >> m_eProflen;
  1619. ar.Read( m_mProf, sizeof(m_mProf) );
  1620. ar.Read( m_eProf, sizeof(m_eProf) );
  1621. time_t temp;
  1622. ar >> temp; m_tmExp = temp;
  1623. ar >> temp; m_tmIns = temp;
  1624. ar >> m_nMaxEvaDays;
  1625. ar >> m_strAR;
  1626. ar >> m_strNSAText;
  1627. SetInsTimeIfNull(); // Write m_tmExp and m_tmIns if it is NULL.
  1628. }
  1629. }
  1630. CSView &AfxGetSView( )
  1631. {
  1632. static CSView g_sview;
  1633. return g_sview;
  1634. }