Leaked source code of windows server 2003
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.

196 lines
5.3 KiB

  1. /*****************************************************************************
  2. *
  3. * DIGuid.c
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * Misc GUID-related helper functions.
  10. *
  11. * Contents:
  12. *
  13. * DICreateGuid
  14. *
  15. *****************************************************************************/
  16. #include "dinputpr.h"
  17. /*****************************************************************************
  18. *
  19. * The sqiffle for this file.
  20. *
  21. *****************************************************************************/
  22. #define sqfl sqflUtil
  23. #ifdef HID_SUPPORT
  24. /*****************************************************************************
  25. *
  26. * Globals
  27. *
  28. *****************************************************************************/
  29. typedef void (__stdcall *UUIDCREATE)(OUT LPGUID pguid);
  30. UUIDCREATE g_UuidCreate;
  31. /*****************************************************************************
  32. *
  33. * @doc INTERNAL
  34. *
  35. * @func void | FakeUuidCreate |
  36. *
  37. * Create a GUID using a fake algorithm that is close enough.
  38. * Since we don't let our GUIDs leave the DirectInput world,
  39. * the uniqueness policy can be relaxed.
  40. *
  41. * OLE generates a GUID as follows:
  42. *
  43. * Get the current local time in FILETIME format.
  44. *
  45. * Add the magic number 0x00146bf33e42c000 = 580819200 seconds =
  46. * 9580320 minutes = 159672 hours = 6653 days, approximately
  47. * 18 years. Who knows why.
  48. *
  49. * Subtract 0x00989680 (approximately 256 seconds). Who
  50. * knows why.
  51. *
  52. * If you combine the above two steps, the net result is to
  53. * add 0x00146bf33daa2980.
  54. *
  55. * The dwLowDateTime of the resulting FILETIME becomes Data1.
  56. *
  57. * The dwHighDateTime of the resulting FILETIME becomes
  58. * Data2 and Data3, except that the high nibble of Data3
  59. * is forced to 1.
  60. *
  61. * The first two bytes of Data4 are a big-endian 10-bit
  62. * sequence counter, with the top bit set and the other
  63. * bits zero.
  64. *
  65. * The last six bytes are the network card identifier.
  66. *
  67. * @parm LPGUID | pguid |
  68. *
  69. * Receives the GUID to create.
  70. *
  71. *****************************************************************************/
  72. void INTERNAL
  73. FakeUuidCreate(LPGUID pguid)
  74. {
  75. LONG lRc;
  76. SYSTEMTIME st;
  77. union {
  78. FILETIME ft;
  79. DWORDLONG ldw;
  80. } u;
  81. GetLocalTime(&st);
  82. SystemTimeToFileTime(&st, &u.ft);
  83. u.ldw += 0x00146BF33DAA2980;
  84. /*
  85. * Note: The wacky pun is actually safe on a RISC because
  86. * Data2 is already dword-aligned.
  87. */
  88. pguid->Data1 = u.ft.dwLowDateTime;
  89. *(LPDWORD)&pguid->Data2 = (u.ft.dwHighDateTime & 0x0FFFFFFF) | 0x10000000;
  90. lRc = Excl_UniqueGuidInteger();
  91. lRc = lRc & 0x3FFF;
  92. pguid->Data4[0] = 0x80 | HIBYTE(lRc);
  93. pguid->Data4[1] = LOBYTE(lRc);
  94. /*
  95. * We use the network adapter ID of the dial-up adapter as our
  96. * network ID. No real network adapter will have this ID.
  97. */
  98. pguid->Data4[2] = 'D';
  99. pguid->Data4[3] = 'E';
  100. pguid->Data4[4] = 'S';
  101. pguid->Data4[5] = 'T';
  102. pguid->Data4[6] = 0x00;
  103. pguid->Data4[7] = 0x00;
  104. }
  105. /*****************************************************************************
  106. *
  107. * @doc INTERNAL
  108. *
  109. * @func void | DICreateGuid |
  110. *
  111. * Create a GUID. Because we don't want to pull in all of OLE,
  112. * we don't actually use RPCRT4.
  113. *
  114. * @parm LPGUID | pguid |
  115. *
  116. * Receives the GUID to create.
  117. *
  118. *****************************************************************************/
  119. void EXTERNAL
  120. DICreateGuid(LPGUID pguid)
  121. {
  122. AssertF(g_hmtxGlobal);
  123. FakeUuidCreate(pguid);
  124. }
  125. /*****************************************************************************
  126. *
  127. * @doc INTERNAL
  128. *
  129. * @func void | DICreateStaticGuid |
  130. *
  131. * Create a "static" <t GUID>, which is a <t GUID> that can be
  132. * deterministically regenerated from its parameters.
  133. *
  134. * This is used to invent <t GUID>s for HID devices
  135. * and vendors.
  136. *
  137. * The entire <t GUID> is zero, except for the pid and vid
  138. * which go into Data1, and the network adapter
  139. * ID is the dial-up adapter.
  140. *
  141. * We put the variable bits into the Data1 because that's
  142. * how GUIDs work.
  143. *
  144. * The resulting GUID is {pidvid-0000-0000-0000-504944564944}
  145. *
  146. * @parm LPGUID | pguid |
  147. *
  148. * Receives the created <t GUID>.
  149. *
  150. *****************************************************************************/
  151. void EXTERNAL
  152. DICreateStaticGuid(LPGUID pguid, WORD pid, WORD vid)
  153. {
  154. pguid->Data1 = MAKELONG(vid, pid);
  155. pguid->Data2 = 0;
  156. pguid->Data3 = 0;
  157. /*
  158. * We use the string "PIDVID" as our network adapter ID.
  159. * No real network adapter will have this ID.
  160. */
  161. pguid->Data4[0] = 0x00;
  162. pguid->Data4[1] = 0x00;
  163. pguid->Data4[2] = 'P';
  164. pguid->Data4[3] = 'I';
  165. pguid->Data4[4] = 'D';
  166. pguid->Data4[5] = 'V';
  167. pguid->Data4[6] = 'I';
  168. pguid->Data4[7] = 'D';
  169. }
  170. #endif