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.

303 lines
6.9 KiB

  1. #include "dpsp.h"
  2. #define REGISTRY_NAMELEN 512
  3. // space (in bytes) for a human readable (unicode) guid + some extra
  4. #define GUID_STRING_SIZE 80
  5. #define SZ_SP_KEY "Software\\Microsoft\\DirectPlay\\Service Providers"
  6. #define SZ_GUID "Guid"
  7. #define SZ_FLAGS "dwFlags"
  8. #undef DPF_MODNAME
  9. #define DPF_MODNAME "FindApplicationInRegistry"
  10. // convert a hex char to an int - used by str to guid conversion
  11. // we wrote our own, since the ole one is slow, and requires ole32.dll
  12. // we use ansi strings here, since guids won't get internationalized
  13. int GetDigit(LPSTR lpstr)
  14. {
  15. char ch = *lpstr;
  16. if (ch >= '0' && ch <= '9')
  17. return(ch - '0');
  18. if (ch >= 'a' && ch <= 'f')
  19. return(ch - 'a' + 10);
  20. if (ch >= 'A' && ch <= 'F')
  21. return(ch - 'A' + 10);
  22. return(0);
  23. }
  24. // walk the string, writing pairs of bytes into the byte stream (guid)
  25. // we need to write the bytes into the byte stream from right to left
  26. // or left to right as indicated by fRightToLeft
  27. void ConvertField(LPBYTE lpByte,LPSTR * ppStr,int iFieldSize,BOOL fRightToLeft)
  28. {
  29. int i;
  30. for (i=0;i<iFieldSize ;i++ )
  31. {
  32. // don't barf on the field separators
  33. if ('-' == **ppStr) (*ppStr)++;
  34. if (fRightToLeft == TRUE)
  35. {
  36. // work from right to left within the byte stream
  37. *(lpByte + iFieldSize - (i+1)) = 16*GetDigit(*ppStr) + GetDigit((*ppStr)+1);
  38. }
  39. else
  40. {
  41. // work from left to right within the byte stream
  42. *(lpByte + i) = 16*GetDigit(*ppStr) + GetDigit((*ppStr)+1);
  43. }
  44. *ppStr+=2; // get next two digit pair
  45. }
  46. } // ConvertField
  47. // convert the passed in string to a real GUID
  48. // walk the guid, setting each byte in the guid to the two digit hex pair in the
  49. // passed string
  50. HRESULT GUIDFromString(LPSTR lpStr, GUID * pGuid)
  51. {
  52. BYTE * lpByte; // byte index into guid
  53. int iFieldSize; // size of current field we're converting
  54. // since its a guid, we can do a "brute force" conversion
  55. // make sure we have a {xxxx-...} type guid
  56. if ('{' != *lpStr) return E_FAIL;
  57. lpStr++;
  58. lpByte = (BYTE *)pGuid;
  59. // data 1
  60. iFieldSize = sizeof(unsigned long);
  61. ConvertField(lpByte,&lpStr,iFieldSize,TRUE);
  62. lpByte += iFieldSize;
  63. // data 2
  64. iFieldSize = sizeof(unsigned short);
  65. ConvertField(lpByte,&lpStr,iFieldSize,TRUE);
  66. lpByte += iFieldSize;
  67. // data 3
  68. iFieldSize = sizeof(unsigned short);
  69. ConvertField(lpByte,&lpStr,iFieldSize,TRUE);
  70. lpByte += iFieldSize;
  71. // data 4
  72. iFieldSize = 8*sizeof(unsigned char);
  73. ConvertField(lpByte,&lpStr,iFieldSize,FALSE);
  74. lpByte += iFieldSize;
  75. // make sure we ended in the right place
  76. if ('}' != *lpStr)
  77. {
  78. DPF_ERR("invalid guid!!");
  79. memset(pGuid,0,sizeof(GUID));
  80. return E_FAIL;
  81. }
  82. return DP_OK;
  83. }// GUIDFromString
  84. BOOL FindSPInRegistry(LPGUID lpguid, LPSTR lpszSPName, DWORD dwNameSize, HKEY * lphkey)
  85. {
  86. HKEY hkeyDPSPs, hkeySP;
  87. DWORD dwIndex = 0;
  88. CHAR szGuidStr[GUID_STRING_SIZE];
  89. DWORD dwGuidStrSize = GUID_STRING_SIZE;
  90. DWORD dwType = REG_SZ;
  91. GUID guidSP;
  92. LONG lReturn;
  93. BOOL bFound = FALSE;
  94. DWORD dwSaveNameSize = dwNameSize;
  95. DPF(7, "Entering FindSPInRegistry");
  96. DPF(9, "Parameters: 0x%08x, 0x%08x, %lu, 0x%08x",
  97. lpguid, lpszSPName, dwNameSize, lphkey);
  98. // Open the Applications key
  99. lReturn = RegOpenKeyExA(HKEY_LOCAL_MACHINE, SZ_SP_KEY, 0,
  100. KEY_READ, &hkeyDPSPs);
  101. if(lReturn != ERROR_SUCCESS)
  102. {
  103. DPF_ERR("Unable to open DPlay service provider registry key!");
  104. return FALSE;
  105. }
  106. // Walk the list of sps in the registry, looking for
  107. // the sp with the right GUID
  108. while(!bFound)
  109. {
  110. // Open the next application key
  111. dwSaveNameSize = dwNameSize;
  112. dwGuidStrSize = GUID_STRING_SIZE;
  113. lReturn = RegEnumKeyExA(hkeyDPSPs, dwIndex++, lpszSPName,
  114. &dwSaveNameSize, NULL, NULL, NULL, NULL);
  115. // If the enum returns no more apps, we want to bail
  116. if(lReturn != ERROR_SUCCESS)
  117. break;
  118. // Open the application key
  119. lReturn = RegOpenKeyExA(hkeyDPSPs, lpszSPName, 0,
  120. KEY_READ, &hkeySP);
  121. if(lReturn != ERROR_SUCCESS)
  122. {
  123. DPF_ERR("Unable to open sp key!");
  124. continue;
  125. }
  126. // Get the GUID of the Game
  127. lReturn = RegQueryValueExA(hkeySP, SZ_GUID, NULL, &dwType,
  128. (LPBYTE)&szGuidStr, &dwGuidStrSize);
  129. if(lReturn != ERROR_SUCCESS)
  130. {
  131. RegCloseKey(hkeySP);
  132. DPF_ERR("Unable to query GUID key value!");
  133. continue;
  134. }
  135. // Convert the string to a real GUID & Compare it to the passed in one
  136. GUIDFromString(szGuidStr, &guidSP);
  137. if(IsEqualGUID(&guidSP, lpguid))
  138. {
  139. bFound = TRUE;
  140. break;
  141. }
  142. // Close the App key
  143. RegCloseKey(hkeySP);
  144. }
  145. // Close the DPApps key
  146. RegCloseKey(hkeyDPSPs);
  147. if(bFound)
  148. *lphkey = hkeySP;
  149. return bFound;
  150. } // FindSPInRegistry
  151. #undef DPF_MODNAME
  152. #define DPF_MODNAME "GetKeyValue"
  153. BOOL GetKeyValue(HKEY hkeyApp, LPSTR lpszKey, DWORD dwType, LPBYTE * lplpValue)
  154. {
  155. DWORD dwSize;
  156. LPBYTE lpTemp = NULL;
  157. LONG lReturn;
  158. DPF(7, "Entering GetKeyValue");
  159. DPF(9, "Parameters: 0x%08x, 0x%08x, 0x%08x",
  160. hkeyApp, lpszKey, lplpValue);
  161. ASSERT(lplpValue);
  162. // Get the size of the buffer for the Path
  163. lReturn = RegQueryValueExA(hkeyApp, lpszKey, NULL, &dwType, NULL, &dwSize);
  164. if(lReturn != ERROR_SUCCESS)
  165. {
  166. DPF_ERR("Error getting size of key value!");
  167. return FALSE;
  168. }
  169. // If the size is 1, then it is an empty string (only contains a
  170. // null terminator). Treat this the same as a NULL string or a
  171. // missing key and fail it.
  172. if(dwSize <= 1)
  173. return FALSE;
  174. ENTER_DPSP();
  175. // Alloc the buffer for the Path
  176. lpTemp = MemAlloc(dwSize);
  177. LEAVE_DPSP();
  178. if(!lpTemp)
  179. {
  180. DPF_ERR("Unable to allocate temporary string for Path!");
  181. return FALSE;
  182. }
  183. // Get the value itself
  184. lReturn = RegQueryValueExA(hkeyApp, lpszKey, NULL, &dwType,
  185. (LPBYTE)lpTemp, &dwSize);
  186. if(lReturn != ERROR_SUCCESS)
  187. {
  188. MemFree(lpTemp);
  189. DPF_ERR("Unable to get key value!");
  190. return FALSE;
  191. }
  192. *lplpValue = lpTemp;
  193. return TRUE;
  194. } // GetKeyValue
  195. #undef DPF_MODNAME
  196. #define DPF_MODNAME "GetFlagsFromRegistry"
  197. HRESULT GetFlagsFromRegistry(LPGUID lpguidSP, LPDWORD lpdwFlags)
  198. {
  199. LPSTR lpszSPName=NULL;
  200. HKEY hkeySP = NULL;
  201. LPBYTE lpValue=NULL;
  202. DWORD dwSize = 0;
  203. HRESULT hr = DP_OK;
  204. DPF(7, "Entering GetFlagsFromRegistry");
  205. DPF(9, "Parameters: 0x%08x, 0x%08x", lpguidSP, lpdwFlags);
  206. ENTER_DPSP();
  207. // Allocate memory for the App Name
  208. lpszSPName = MemAlloc(REGISTRY_NAMELEN);
  209. LEAVE_DPSP();
  210. if(!lpszSPName)
  211. {
  212. DPF_ERR("Unable to allocate memory for sp name!");
  213. return E_OUTOFMEMORY;
  214. }
  215. // Open the registry key for the App
  216. if(!FindSPInRegistry(lpguidSP, lpszSPName,REGISTRY_NAMELEN, &hkeySP))
  217. {
  218. DPF_ERR("Unable to find sp in registry!");
  219. hr = E_FAIL;
  220. goto CLEANUP_EXIT;
  221. }
  222. // Get the port value.
  223. if(!GetKeyValue(hkeySP, SZ_FLAGS, REG_BINARY, &lpValue))
  224. {
  225. DPF_ERR("Unable to get flags value from registry!");
  226. hr = E_FAIL;
  227. goto CLEANUP_EXIT;
  228. }
  229. *lpdwFlags = *(LPDWORD)lpValue;
  230. // fall through
  231. CLEANUP_EXIT:
  232. if (lpszSPName) MemFree(lpszSPName);
  233. if (lpValue) MemFree(lpValue);
  234. // Close the Apps key
  235. if(hkeySP)
  236. RegCloseKey(hkeySP);
  237. return hr;
  238. } // GetFlagsFromRegistry