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.

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