Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

531 lines
15 KiB

  1. #ifndef __glos_h_
  2. #define __glos_h_
  3. /*
  4. ** Copyright 1991, 1992, 1993, Silicon Graphics, Inc.
  5. ** All Rights Reserved.
  6. **
  7. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  8. ** the contents of this file may not be disclosed to third parties, copied or
  9. ** duplicated in any form, in whole or in part, without the prior written
  10. ** permission of Silicon Graphics, Inc.
  11. **
  12. ** RESTRICTED RIGHTS LEGEND:
  13. ** Use, duplication or disclosure by the Government is subject to restrictions
  14. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  15. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  16. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  17. ** rights reserved under the Copyright Laws of the United States.
  18. */
  19. #include <nt.h>
  20. #include <stdlib.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <stddef.h>
  24. #include <windows.h>
  25. #include "glscreen.h"
  26. #include "types.h"
  27. // Indicator of which platform we're running on,
  28. // uses the VER_PLATFORM defines
  29. extern DWORD dwPlatformId;
  30. //
  31. // LocalRtlFillMemoryUlong
  32. //
  33. // Inline implementation of RtlFillMemoryUlong. Destination has DWORD
  34. // alignment.
  35. //
  36. // Parameters:
  37. //
  38. // Destination pointer to DWORD aligned destination
  39. // Length number of bytes to fill
  40. // Pattern fill pattern
  41. //
  42. _inline VOID LocalRtlFillMemoryUlong(PVOID Destination, ULONG Length,
  43. ULONG Pattern)
  44. {
  45. if ((Pattern == 0) || (Pattern == 0xffffffff))
  46. memset(Destination, Pattern, Length);
  47. else {
  48. register ULONG *pDest = (ULONG *)Destination;
  49. LONG unroll;
  50. Length >>= 2;
  51. for (unroll = Length >> 5; unroll; unroll--) {
  52. pDest[0] = Pattern; pDest[1] = Pattern;
  53. pDest[2] = Pattern; pDest[3] = Pattern;
  54. pDest[4] = Pattern; pDest[5] = Pattern;
  55. pDest[6] = Pattern; pDest[7] = Pattern;
  56. pDest[8] = Pattern; pDest[9] = Pattern;
  57. pDest[10] = Pattern; pDest[11] = Pattern;
  58. pDest[12] = Pattern; pDest[13] = Pattern;
  59. pDest[14] = Pattern; pDest[15] = Pattern;
  60. pDest[16] = Pattern; pDest[17] = Pattern;
  61. pDest[18] = Pattern; pDest[19] = Pattern;
  62. pDest[20] = Pattern; pDest[21] = Pattern;
  63. pDest[22] = Pattern; pDest[23] = Pattern;
  64. pDest[24] = Pattern; pDest[25] = Pattern;
  65. pDest[26] = Pattern; pDest[27] = Pattern;
  66. pDest[28] = Pattern; pDest[29] = Pattern;
  67. pDest[30] = Pattern; pDest[31] = Pattern;
  68. pDest += 32;
  69. }
  70. for (unroll = (Length & 0x1f) >> 2; unroll; unroll--) {
  71. pDest[0] = Pattern; pDest[1] = Pattern;
  72. pDest[2] = Pattern; pDest[3] = Pattern;
  73. pDest += 4;
  74. }
  75. for (unroll = (Length & 0x3) - 1; unroll >= 0; unroll--)
  76. pDest[unroll] = Pattern;
  77. }
  78. }
  79. //
  80. // LocalCompareUlongMemory
  81. //
  82. // Inline implementation of RtlCompareUlongMemory. Both pointers
  83. // must have DWORD alignment.
  84. //
  85. // Returns TRUE if the two source arrays are equal. FALSE otherwise.
  86. //
  87. // Parameters:
  88. //
  89. // Source1 pointer to DWORD aligned array to check
  90. // Source1 pointer to DWORD aligned array to compare with
  91. // Length number of bytes to fill
  92. //
  93. _inline BOOL LocalCompareUlongMemory(PVOID Source1, PVOID Source2,
  94. ULONG Length)
  95. {
  96. register ULONG *pSrc1 = (ULONG *) Source1;
  97. register ULONG *pSrc2 = (ULONG *) Source2;
  98. LONG unroll;
  99. BOOL bRet = FALSE;
  100. Length >>= 2;
  101. for (unroll = Length >> 5; unroll; unroll--) {
  102. if ( (pSrc1[0] != pSrc2[0]) || (pSrc1[1] != pSrc2[1]) ||
  103. (pSrc1[2] != pSrc2[2]) || (pSrc1[3] != pSrc2[3]) ||
  104. (pSrc1[4] != pSrc2[4]) || (pSrc1[5] != pSrc2[5]) ||
  105. (pSrc1[6] != pSrc2[6]) || (pSrc1[7] != pSrc2[7]) ||
  106. (pSrc1[8] != pSrc2[8]) || (pSrc1[9] != pSrc2[9]) ||
  107. (pSrc1[10] != pSrc2[10]) || (pSrc1[11] != pSrc2[11]) ||
  108. (pSrc1[12] != pSrc2[12]) || (pSrc1[13] != pSrc2[13]) ||
  109. (pSrc1[14] != pSrc2[14]) || (pSrc1[15] != pSrc2[15]) ||
  110. (pSrc1[16] != pSrc2[16]) || (pSrc1[17] != pSrc2[17]) ||
  111. (pSrc1[18] != pSrc2[18]) || (pSrc1[19] != pSrc2[19]) ||
  112. (pSrc1[20] != pSrc2[20]) || (pSrc1[21] != pSrc2[21]) ||
  113. (pSrc1[22] != pSrc2[22]) || (pSrc1[23] != pSrc2[23]) ||
  114. (pSrc1[24] != pSrc2[24]) || (pSrc1[25] != pSrc2[25]) ||
  115. (pSrc1[26] != pSrc2[26]) || (pSrc1[27] != pSrc2[27]) ||
  116. (pSrc1[28] != pSrc2[28]) || (pSrc1[29] != pSrc2[29]) ||
  117. (pSrc1[30] != pSrc2[30]) || (pSrc1[31] != pSrc2[31]) )
  118. goto LocalRtlCompareUlongMemory_exit;
  119. pSrc1 += 32;
  120. pSrc2 += 32;
  121. }
  122. for (unroll = (Length & 0x1f) >> 2; unroll; unroll--) {
  123. if ( (pSrc1[0] != pSrc2[0]) || (pSrc1[1] != pSrc2[1]) ||
  124. (pSrc1[2] != pSrc2[2]) || (pSrc1[3] != pSrc2[3]) )
  125. goto LocalRtlCompareUlongMemory_exit;
  126. pSrc1 += 4;
  127. pSrc2 += 4;
  128. }
  129. for (unroll = (Length & 0x3) - 1; unroll >= 0; unroll--)
  130. if ( pSrc1[unroll] != pSrc2[unroll] )
  131. goto LocalRtlCompareUlongMemory_exit;
  132. bRet = TRUE; // return TRUE if memory is identical
  133. LocalRtlCompareUlongMemory_exit:
  134. return bRet;
  135. }
  136. //
  137. // LocalRtlFillMemoryUshort
  138. //
  139. // Inline implementation of USHORT equivalent to RtlFillMemoryUlong,
  140. // RtlFillMemoryUshort (does not currently exist in NT). WORD alignment
  141. // assumed for Destination.
  142. //
  143. // Parameters:
  144. //
  145. // Destination pointer to USHORT aligned destination
  146. // Length number of bytes to fill
  147. // Pattern fill pattern
  148. //
  149. _inline VOID LocalRtlFillMemoryUshort(PVOID Destination, ULONG Length,
  150. USHORT Pattern)
  151. {
  152. if ( Length == 0 )
  153. return;
  154. // If odd WORD, make it DWORD aligned by writing a WORD up front.
  155. if ( ((ULONG_PTR) Destination) & 0x2 )
  156. {
  157. *((USHORT *) Destination)++ = Pattern;
  158. Length -= sizeof(USHORT);
  159. if ( Length == 0 )
  160. return;
  161. }
  162. // Now the Destination start is DWORD aligned. If the remaining length
  163. // is an odd number of WORDs, we will need to pick up an extra WORD write
  164. // at the end.
  165. if ((Pattern == 0x0000) || (Pattern == 0xffff))
  166. memset(Destination, Pattern, Length);
  167. else {
  168. ULONG ulPattern = Pattern | (Pattern << 16);
  169. ULONG cjDwords;
  170. // Do what we can with DWORD writes.
  171. if ( cjDwords = (Length & (~3)) )
  172. {
  173. LocalRtlFillMemoryUlong((PVOID) Destination, cjDwords, ulPattern);
  174. ((BYTE *) Destination) += cjDwords;
  175. }
  176. // Pick up the last WORD.
  177. if ( Length & 3 )
  178. *((USHORT *) Destination) = Pattern;
  179. }
  180. }
  181. //
  182. // LocalRtlFillMemory24
  183. //
  184. // Inline implementation of 24bit equivalent to RtlFillMemoryUlong,
  185. // No assumptions made about alignment.
  186. // Parameters:
  187. //
  188. // Destination pointer to destination
  189. // Length number of bytes to fill
  190. // col0, col1, col2 Colors
  191. //
  192. _inline VOID LocalRtlFillMemory24(PVOID Destination, ULONG Length,
  193. BYTE col0, BYTE col1, BYTE col2)
  194. {
  195. BYTE col[3];
  196. if ( Length == 0 )
  197. return;
  198. // Check for special cases, same valued components
  199. if ((col0 == col1) && (col0 == col2)) {
  200. memset(Destination, col0, Length);
  201. } else { //Other colors
  202. ULONG ulPat1, ulPat2, ulPat3;
  203. int rem;
  204. int i, tmp;
  205. register ULONG *pDest;
  206. register BYTE *pByte = (BYTE *)Destination;
  207. LONG unroll;
  208. // If not DWORD aligned, make it DWORD aligned.
  209. tmp = (int)((ULONG_PTR) Destination & 0x3);
  210. switch ( 4 - tmp ) {
  211. case 1:
  212. *pByte++ = col0;
  213. Length--;
  214. ulPat1 = (col1 << 24) | (col0 << 16) | (col2 << 8) | col1;
  215. ulPat2 = (col2 << 24) | (col1 << 16) | (col0 << 8) | col2;
  216. ulPat3 = (col0 << 24) | (col2 << 16) | (col1 << 8) | col0;
  217. break;
  218. case 2:
  219. *pByte++ = col0;
  220. *pByte++ = col1;
  221. Length -= 2;
  222. ulPat1 = (col2 << 24) | (col1 << 16) | (col0 << 8) | col2;
  223. ulPat2 = (col0 << 24) | (col2 << 16) | (col1 << 8) | col0;
  224. ulPat3 = (col1 << 24) | (col0 << 16) | (col2 << 8) | col1;
  225. break;
  226. case 3:
  227. *pByte++ = col0;
  228. *pByte++ = col1;
  229. *pByte++ = col2;
  230. Length -= 3;
  231. case 4: // fall thru, 'cause the pattern is the same
  232. default:
  233. ulPat1 = (col0 << 24) | (col2 << 16) | (col1 << 8) | col0;
  234. ulPat2 = (col1 << 24) | (col0 << 16) | (col2 << 8) | col1;
  235. ulPat3 = (col2 << 24) | (col1 << 16) | (col0 << 8) | col2;
  236. }
  237. pDest = (ULONG *)pByte;
  238. rem = Length % 48;
  239. Length >>= 2;
  240. for (unroll = Length/12; unroll; unroll--) {
  241. pDest[0] = ulPat1; pDest[1] = ulPat2;
  242. pDest[2] = ulPat3; pDest[3] = ulPat1;
  243. pDest[4] = ulPat2; pDest[5] = ulPat3;
  244. pDest[6] = ulPat1; pDest[7] = ulPat2;
  245. pDest[8] = ulPat3; pDest[9] = ulPat1;
  246. pDest[10] = ulPat2; pDest[11] = ulPat3;
  247. pDest += 12;
  248. }
  249. col[0] = (BYTE) (ulPat1 & 0x000000ff);
  250. col[1] = (BYTE) ((ulPat1 & 0x0000ff00) >> 8);
  251. col[2] = (BYTE) ((ulPat1 & 0x00ff0000) >> 16);
  252. pByte = (BYTE *)pDest;
  253. for (i=0; i<rem; i++) *pByte++ = col [i%3];
  254. }
  255. }
  256. //
  257. // LocalWriteMemoryAlign
  258. //
  259. // Inline implementation of RtlCopyMemory that ensures that the copy
  260. // operation will write to the destination with DWORD alignment.
  261. //
  262. _inline VOID LocalWriteMemoryAlign(PBYTE pjDst, PBYTE pjSrc, ULONG cj)
  263. {
  264. ULONG cjExtraBytes;
  265. ULONG cjDwords;
  266. // If cj < sizeof(DWORD), then set cjExtraBytes to cj. That's all we will
  267. // need to do.
  268. //
  269. // Otherwise, compute the number of leading bytes to the next DWORD boundary.
  270. if ( cj < 4 )
  271. cjExtraBytes = cj;
  272. else
  273. cjExtraBytes = (ULONG)(4 - (((ULONG_PTR) pjDst) & 3)) & 3;
  274. // Make dst array DWORD aligned by copying the leading non-DWORD aligned bytes.
  275. if ( cjExtraBytes )
  276. {
  277. switch (cjExtraBytes)
  278. {
  279. case 3: *pjDst++ = *pjSrc++;
  280. case 2: *pjDst++ = *pjSrc++;
  281. case 1: *pjDst++ = *pjSrc++;
  282. }
  283. if ( (cj -= cjExtraBytes) == 0 )
  284. return;
  285. }
  286. // Now the beginning of dst array is DWORD aligned. If the remaining length
  287. // is an odd number of BYTEs, we will need to pick up the extra BYTE writes
  288. // at the end.
  289. // Do what we can with DWORD copy.
  290. if ( cjDwords = (cj & (~3)) )
  291. {
  292. memcpy(pjDst, pjSrc, cjDwords);
  293. pjDst += cjDwords;
  294. pjSrc += cjDwords;
  295. }
  296. // Pick up the remaining BYTES.
  297. if ( cjExtraBytes = (cj & 3) )
  298. {
  299. switch (cjExtraBytes)
  300. {
  301. case 3: *pjDst++ = *pjSrc++;
  302. case 2: *pjDst++ = *pjSrc++;
  303. case 1: *pjDst++ = *pjSrc++;
  304. }
  305. }
  306. }
  307. //
  308. // LocalReadMemoryAlign
  309. //
  310. // Inline implementation of RtlCopyMemory that ensures that the copy
  311. // operation will read from the source with DWORD alignment.
  312. //
  313. _inline VOID LocalReadMemoryAlign(PBYTE pjDst, PBYTE pjSrc, ULONG cj)
  314. {
  315. ULONG cjExtraBytes;
  316. ULONG cjDwords;
  317. // If cj < sizeof(DWORD), then set cjExtraBytes to cj. That's all we will
  318. // need to do.
  319. //
  320. // Otherwise, compute the number of leading bytes to the next DWORD boundary.
  321. if ( cj < 4 )
  322. cjExtraBytes = cj;
  323. else
  324. cjExtraBytes = (ULONG) (4 - (((ULONG_PTR) pjSrc) & 3)) & 3;
  325. // Take care of the leading BYTES.
  326. if ( cjExtraBytes )
  327. {
  328. switch (cjExtraBytes)
  329. {
  330. case 3: *pjDst++ = *pjSrc++;
  331. case 2: *pjDst++ = *pjSrc++;
  332. case 1: *pjDst++ = *pjSrc++;
  333. }
  334. if ( (cj -= cjExtraBytes) == 0 )
  335. return;
  336. }
  337. // Now the beginning of src array is DWORD aligned. If the remaining length
  338. // is an odd number of BYTEs, we will need to pick up the extra BYTE writes
  339. // at the end.
  340. // Do what we can with DWORD copy.
  341. if ( cjDwords = (cj & (~3)) )
  342. {
  343. memcpy(pjDst, pjSrc, cjDwords);
  344. pjDst += cjDwords;
  345. pjSrc += cjDwords;
  346. }
  347. // Pick up the remaining BYTES.
  348. if ( cjExtraBytes = (cj & 3) )
  349. {
  350. switch (cjExtraBytes)
  351. {
  352. case 3: *pjDst++ = *pjSrc++;
  353. case 2: *pjDst++ = *pjSrc++;
  354. case 1: *pjDst++ = *pjSrc++;
  355. }
  356. }
  357. }
  358. //
  359. // LocalFillMemory
  360. //
  361. // Inline implementation of RtlFillMemory. Assume that pjDst has only BYTE
  362. // alignment.
  363. //
  364. _inline VOID LocalFillMemory(PBYTE pjDst, ULONG cj, BYTE j)
  365. {
  366. ULONG cjExtraBytes;
  367. ULONG cjDwords;
  368. // If cj < sizeof(DWORD), then set cjExtraBytes to cj. That's all we will
  369. // need to do.
  370. //
  371. // Otherwise, compute the number of leading bytes to the next DWORD boundary.
  372. if ( cj < 4 )
  373. cjExtraBytes = cj;
  374. else
  375. cjExtraBytes = (ULONG)(4 - (((ULONG_PTR) pjDst) & 3)) & 3;
  376. // Take care of the leading BYTES.
  377. if ( cjExtraBytes )
  378. {
  379. switch ( cjExtraBytes )
  380. {
  381. case 3: *pjDst++ = j;
  382. case 2: *pjDst++ = j;
  383. case 1: *pjDst++ = j;
  384. }
  385. if ( (cj -= cjExtraBytes) == 0 )
  386. return;
  387. }
  388. // Now both arrays start is DWORD aligned. If the remaining length
  389. // is an odd number of BYTEs, we will need to pick up the extra BYTE writes
  390. // at the end.
  391. // Do what we can with DWORD copy.
  392. if ( cjDwords = (cj & (~3)) )
  393. {
  394. ULONG ul = j | (j<<8) | (j<<16) | (j<<24);
  395. LocalRtlFillMemoryUlong((PVOID) pjDst, cjDwords, ul);
  396. pjDst += cjDwords;
  397. }
  398. // Pick up the remaining BYTES.
  399. if ( cjExtraBytes = (cj & 3) )
  400. {
  401. switch (cjExtraBytes)
  402. {
  403. case 3: *pjDst++ = j;
  404. case 2: *pjDst++ = j;
  405. case 1: *pjDst++ = j;
  406. }
  407. }
  408. }
  409. //
  410. // LocalZeroMemory
  411. //
  412. // Inline implementation of RtlFillMemory. Assume that pjDst has only BYTE
  413. // alignment.
  414. //
  415. _inline VOID LocalZeroMemory(PBYTE pjDst, ULONG cj)
  416. {
  417. LocalFillMemory(pjDst, cj, 0);
  418. }
  419. #undef RtlMoveMemory
  420. #undef RtlCopyMemory
  421. #undef RtlFillMemory
  422. #undef RtlZeroMemory
  423. #undef RtlFillMemoryUlong
  424. #undef RtlFillMemory24
  425. #define RtlMoveMemory(d, s, l) memmove((d),(s),(l))
  426. #define RtlCopyMemory(d, s, l) memcpy((d),(s),(l))
  427. #define RtlFillMemoryUlong(d, cj, ul) LocalRtlFillMemoryUlong((PVOID)(d),(ULONG)(cj),(ULONG)(ul))
  428. #define RtlFillMemoryUshort(d, cj, us) LocalRtlFillMemoryUshort((PVOID)(d),(ULONG)(cj),(USHORT)(us))
  429. #define RtlFillMemory24(d, cj, c0, c1, c2) LocalRtlFillMemory24((PVOID)(d),(ULONG)(cj),(BYTE)c0,(BYTE)c1,(BYTE)c2)
  430. // RtlCopyMemory_UnalignedDst should be used if the src is guaranteed to have
  431. // DWORD alignment, but the dst does not.
  432. //
  433. // RtlCopyMemory_UnalignedSrc should be used if the dst is guaranteed to have
  434. // DWORD alignment, but the src does not.
  435. #if defined(i386)
  436. #define RtlFillMemory(d, cj, j) LocalFillMemory((PBYTE)(d),(ULONG)(cj),(BYTE)(j))
  437. #define RtlZeroMemory(d, cj) LocalZeroMemory((PBYTE)(d),(ULONG)(cj))
  438. #define RtlCopyMemory_UnalignedDst(d, s, l) LocalWriteMemoryAlign((PBYTE)(d),(PBYTE)(s),(ULONG)(l))
  439. #define RtlCopyMemory_UnalignedSrc(d, s, l) LocalReadMemoryAlign((PBYTE)(d),(PBYTE)(s),(ULONG)(l))
  440. #else
  441. #define RtlFillMemory(d, cj, j) memset((d),(j),(cj))
  442. #define RtlZeroMemory(d, cj) memset((d),0,(cj))
  443. #define RtlCopyMemory_UnalignedDst(d, s, l) memcpy((d),(s),(l))
  444. #define RtlCopyMemory_UnalignedSrc(d, s, l) memcpy((d),(s),(l))
  445. #endif
  446. #include "oleauto.h"
  447. #include "batchinf.h"
  448. #include "glteb.h"
  449. #include "debug.h"
  450. #include "asm.h"
  451. #endif /* __glos_h_ */