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.

459 lines
11 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 - 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: registry.c
  6. *
  7. * History:
  8. * Date By Reason
  9. * ==== == ======
  10. * ???
  11. * 12/28/99 aarono added query for required key for Win95 rsip support
  12. * 04/19/01 vanceo added nathelp DLL retrieval and copied to dplaysvr
  13. *
  14. ***************************************************************************/
  15. #include "dpsp.h"
  16. #define REGISTRY_NAMELEN 512
  17. // space (in bytes) for a human readable (unicode) guid + some extra
  18. #define GUID_STRING_SIZE 80
  19. #define SZ_SP_KEY "Software\\Microsoft\\DirectPlay\\Service Providers"
  20. #define SZ_GUID "Guid"
  21. #define SZ_FLAGS "dwFlags"
  22. #define SZ_GATEWAY "Gateway"
  23. #define SZ_NATHELP "NATHelp"
  24. #undef DPF_MODNAME
  25. #define DPF_MODNAME "FindApplicationInRegistry"
  26. // convert a hex char to an int - used by str to guid conversion
  27. // we wrote our own, since the ole one is slow, and requires ole32.dll
  28. // we use ansi strings here, since guids won't get internationalized
  29. int GetDigit(LPSTR lpstr)
  30. {
  31. char ch = *lpstr;
  32. if (ch >= '0' && ch <= '9')
  33. return(ch - '0');
  34. if (ch >= 'a' && ch <= 'f')
  35. return(ch - 'a' + 10);
  36. if (ch >= 'A' && ch <= 'F')
  37. return(ch - 'A' + 10);
  38. return(0);
  39. }
  40. // walk the string, writing pairs of bytes into the byte stream (guid)
  41. // we need to write the bytes into the byte stream from right to left
  42. // or left to right as indicated by fRightToLeft
  43. void ConvertField(LPBYTE lpByte,LPSTR * ppStr,int iFieldSize,BOOL fRightToLeft)
  44. {
  45. int i;
  46. for (i=0;i<iFieldSize ;i++ )
  47. {
  48. // don't barf on the field separators
  49. if ('-' == **ppStr) (*ppStr)++;
  50. if (fRightToLeft == TRUE)
  51. {
  52. // work from right to left within the byte stream
  53. *(lpByte + iFieldSize - (i+1)) = 16*GetDigit(*ppStr) + GetDigit((*ppStr)+1);
  54. }
  55. else
  56. {
  57. // work from left to right within the byte stream
  58. *(lpByte + i) = 16*GetDigit(*ppStr) + GetDigit((*ppStr)+1);
  59. }
  60. *ppStr+=2; // get next two digit pair
  61. }
  62. } // ConvertField
  63. // convert the passed in string to a real GUID
  64. // walk the guid, setting each byte in the guid to the two digit hex pair in the
  65. // passed string
  66. HRESULT GUIDFromString(LPSTR lpStr, GUID * pGuid)
  67. {
  68. BYTE * lpByte; // byte index into guid
  69. int iFieldSize; // size of current field we're converting
  70. // since its a guid, we can do a "brute force" conversion
  71. // make sure we have a {xxxx-...} type guid
  72. if ('{' != *lpStr) return E_FAIL;
  73. lpStr++;
  74. lpByte = (BYTE *)pGuid;
  75. // data 1
  76. iFieldSize = sizeof(unsigned long);
  77. ConvertField(lpByte,&lpStr,iFieldSize,TRUE);
  78. lpByte += iFieldSize;
  79. // data 2
  80. iFieldSize = sizeof(unsigned short);
  81. ConvertField(lpByte,&lpStr,iFieldSize,TRUE);
  82. lpByte += iFieldSize;
  83. // data 3
  84. iFieldSize = sizeof(unsigned short);
  85. ConvertField(lpByte,&lpStr,iFieldSize,TRUE);
  86. lpByte += iFieldSize;
  87. // data 4
  88. iFieldSize = 8*sizeof(unsigned char);
  89. ConvertField(lpByte,&lpStr,iFieldSize,FALSE);
  90. lpByte += iFieldSize;
  91. // make sure we ended in the right place
  92. if ('}' != *lpStr)
  93. {
  94. DPF_ERR("invalid guid!!");
  95. memset(pGuid,0,sizeof(GUID));
  96. return E_FAIL;
  97. }
  98. return DP_OK;
  99. }// GUIDFromString
  100. BOOL FindSPInRegistry(LPGUID lpguid, LPSTR lpszSPName, DWORD dwNameSize, HKEY * lphkey)
  101. {
  102. HKEY hkeyDPSPs, hkeySP;
  103. DWORD dwIndex = 0;
  104. CHAR szGuidStr[GUID_STRING_SIZE];
  105. DWORD dwGuidStrSize = GUID_STRING_SIZE;
  106. DWORD dwType = REG_SZ;
  107. GUID guidSP;
  108. LONG lReturn;
  109. BOOL bFound = FALSE;
  110. DWORD dwSaveNameSize = dwNameSize;
  111. DPF(7, "Entering FindSPInRegistry");
  112. DPF(8, "Parameters: 0x%08x, 0x%08x, %lu, 0x%08x",
  113. lpguid, lpszSPName, dwNameSize, lphkey);
  114. // Open the Applications key
  115. lReturn = RegOpenKeyExA(HKEY_LOCAL_MACHINE, SZ_SP_KEY, 0,
  116. KEY_READ, &hkeyDPSPs);
  117. if(lReturn != ERROR_SUCCESS)
  118. {
  119. DPF_ERR("Unable to open DPlay service provider registry key!");
  120. return FALSE;
  121. }
  122. // Walk the list of sps in the registry, looking for
  123. // the sp with the right GUID
  124. while(!bFound)
  125. {
  126. // Open the next SP key
  127. dwSaveNameSize = dwNameSize;
  128. dwGuidStrSize = GUID_STRING_SIZE;
  129. lReturn = RegEnumKeyExA(hkeyDPSPs, dwIndex++, lpszSPName,
  130. &dwSaveNameSize, NULL, NULL, NULL, NULL);
  131. // If the enum returns no more SPs, we want to bail
  132. if(lReturn != ERROR_SUCCESS)
  133. break;
  134. // Open the SP key
  135. lReturn = RegOpenKeyExA(hkeyDPSPs, lpszSPName, 0,
  136. KEY_READ, &hkeySP);
  137. if(lReturn != ERROR_SUCCESS)
  138. {
  139. DPF_ERR("Unable to open sp key!");
  140. continue;
  141. }
  142. // Get the GUID of the SP
  143. lReturn = RegQueryValueExA(hkeySP, SZ_GUID, NULL, &dwType,
  144. (LPBYTE)szGuidStr, &dwGuidStrSize);
  145. if(lReturn != ERROR_SUCCESS)
  146. {
  147. RegCloseKey(hkeySP);
  148. DPF_ERR("Unable to query GUID key value!");
  149. continue;
  150. }
  151. // Convert the string to a real GUID & Compare it to the passed in one
  152. GUIDFromString(szGuidStr, &guidSP);
  153. if(IsEqualGUID(&guidSP, lpguid))
  154. {
  155. bFound = TRUE;
  156. break;
  157. }
  158. // Close the SP key
  159. RegCloseKey(hkeySP);
  160. }
  161. // Close the SPs key
  162. RegCloseKey(hkeyDPSPs);
  163. if(bFound)
  164. *lphkey = hkeySP;
  165. return bFound;
  166. } // FindSPInRegistry
  167. #undef DPF_MODNAME
  168. #define DPF_MODNAME "GetKeyValue"
  169. BOOL GetKeyValue(HKEY hkeyApp, LPSTR lpszKey, DWORD dwType, LPBYTE * lplpValue)
  170. {
  171. DWORD dwSize;
  172. LPBYTE lpTemp = NULL;
  173. LONG lReturn;
  174. DPF(7, "Entering GetKeyValue");
  175. DPF(8, "Parameters: 0x%08x, 0x%08x, 0x%08x",
  176. hkeyApp, lpszKey, lplpValue);
  177. ASSERT(lplpValue);
  178. // Get the size of the buffer for the Path
  179. lReturn = RegQueryValueExA(hkeyApp, lpszKey, NULL, &dwType, NULL, &dwSize);
  180. if(lReturn != ERROR_SUCCESS)
  181. {
  182. DPF_ERR("Error getting size of key value!");
  183. return FALSE;
  184. }
  185. // If the size is 1, then it is an empty string (only contains a
  186. // null terminator). Treat this the same as a NULL string or a
  187. // missing key and fail it.
  188. if(dwSize <= 1)
  189. return FALSE;
  190. ENTER_DPSP();
  191. // Alloc the buffer for the Path
  192. lpTemp = SP_MemAlloc(dwSize);
  193. LEAVE_DPSP();
  194. if(!lpTemp)
  195. {
  196. DPF_ERR("Unable to allocate temporary string for Path!");
  197. return FALSE;
  198. }
  199. // Get the value itself
  200. lReturn = RegQueryValueExA(hkeyApp, lpszKey, NULL, &dwType,
  201. (LPBYTE)lpTemp, &dwSize);
  202. if(lReturn != ERROR_SUCCESS)
  203. {
  204. SP_MemFree(lpTemp);
  205. DPF_ERR("Unable to get key value!");
  206. return FALSE;
  207. }
  208. *lplpValue = lpTemp;
  209. return TRUE;
  210. } // GetKeyValue
  211. #undef DPF_MODNAME
  212. #define DPF_MODNAME "GetFlagsFromRegistry"
  213. HRESULT GetFlagsFromRegistry(LPGUID lpguidSP, LPDWORD lpdwFlags)
  214. {
  215. LPSTR lpszSPName=NULL;
  216. HKEY hkeySP = NULL;
  217. LPBYTE lpValue=NULL;
  218. DWORD dwSize = 0;
  219. HRESULT hr = DP_OK;
  220. DPF(7, "Entering GetFlagsFromRegistry");
  221. DPF(8, "Parameters: 0x%08x, 0x%08x", lpguidSP, lpdwFlags);
  222. ENTER_DPSP();
  223. // Allocate memory for the App Name
  224. lpszSPName = SP_MemAlloc(REGISTRY_NAMELEN);
  225. LEAVE_DPSP();
  226. if(!lpszSPName)
  227. {
  228. DPF_ERR("Unable to allocate memory for sp name!");
  229. return E_OUTOFMEMORY;
  230. }
  231. // Open the registry key for the App
  232. if(!FindSPInRegistry(lpguidSP, lpszSPName,REGISTRY_NAMELEN, &hkeySP))
  233. {
  234. DPF_ERR("Unable to find sp in registry!");
  235. hr = E_FAIL;
  236. goto CLEANUP_EXIT;
  237. }
  238. // Get the port value.
  239. if(!GetKeyValue(hkeySP, SZ_FLAGS, REG_BINARY, &lpValue))
  240. {
  241. DPF_ERR("Unable to get flags value from registry!");
  242. hr = E_FAIL;
  243. goto CLEANUP_EXIT;
  244. }
  245. *lpdwFlags = *(LPDWORD)lpValue;
  246. // fall through
  247. CLEANUP_EXIT:
  248. if (lpszSPName) SP_MemFree(lpszSPName);
  249. if (lpValue) SP_MemFree(lpValue);
  250. // Close the Apps key
  251. if(hkeySP)
  252. RegCloseKey(hkeySP);
  253. return hr;
  254. } // GetFlagsFromRegistry
  255. #if USE_RSIP
  256. #undef DPF_MODNAME
  257. #define DPF_MODNAME "GetGatewayFromRegistry"
  258. HRESULT GetGatewayFromRegistry(LPGUID lpguidSP, LPBYTE lpszGateway, DWORD cbszGateway)
  259. {
  260. LPSTR lpszSPName=NULL;
  261. HKEY hkeySP = NULL;
  262. LPBYTE lpValue=NULL;
  263. DWORD dwSize = 0;
  264. HRESULT hr = DP_OK;
  265. DPF(7, "Entering GetGatewayFromRegistry");
  266. DPF(8, "Parameters: 0x%08x, 0x%08x %d", lpguidSP, lpszGateway, cbszGateway);
  267. ENTER_DPSP();
  268. // Allocate memory for the SP Name
  269. lpszSPName = SP_MemAlloc(REGISTRY_NAMELEN);
  270. LEAVE_DPSP();
  271. if(!lpszSPName)
  272. {
  273. DPF_ERR("Unable to allocate memory for sp name!");
  274. return E_OUTOFMEMORY;
  275. }
  276. // Open the registry key for the SP
  277. if(!FindSPInRegistry(lpguidSP, lpszSPName,REGISTRY_NAMELEN, &hkeySP))
  278. {
  279. DPF_ERR("Unable to find sp in registry!");
  280. hr = E_FAIL;
  281. goto CLEANUP_EXIT;
  282. }
  283. // Get the gateway value.
  284. if(!GetKeyValue(hkeySP, SZ_GATEWAY, REG_SZ, &lpValue))
  285. {
  286. DPF_ERR("Unable to get key value from registry!");
  287. hr = E_FAIL;
  288. goto CLEANUP_EXIT;
  289. }
  290. dwSize = strlen(lpValue)+1;
  291. if(dwSize > cbszGateway){
  292. DPF_ERR("Not enough room for gateway address");
  293. goto CLEANUP_EXIT;
  294. }
  295. memcpy(lpszGateway, lpValue, dwSize);
  296. // fall through
  297. CLEANUP_EXIT:
  298. if (lpszSPName) SP_MemFree(lpszSPName);
  299. if (lpValue) SP_MemFree(lpValue);
  300. // Close the Apps key
  301. if(hkeySP)
  302. RegCloseKey(hkeySP);
  303. return hr;
  304. } // GetGatewayFromRegistry
  305. #elif USE_NATHELP // ! USE_RSIP
  306. #undef DPF_MODNAME
  307. #define DPF_MODNAME "GetNATHelpDLLFromRegistry"
  308. HRESULT GetNATHelpDLLFromRegistry(LPGUID lpguidSP, LPBYTE lpszNATHelpDLL, DWORD cbszNATHelpDLL)
  309. {
  310. LPSTR lpszSPName=NULL;
  311. HKEY hkeySP = NULL;
  312. LPBYTE lpValue=NULL;
  313. DWORD dwSize = 0;
  314. HRESULT hr = DP_OK;
  315. DPF(7, "Entering GetNATHelpDLLFromRegistry");
  316. DPF(8, "Parameters: 0x%08x, 0x%08x %d", lpguidSP, lpszNATHelpDLL, cbszNATHelpDLL);
  317. ENTER_DPSP();
  318. // Allocate memory for the SP Name
  319. lpszSPName = SP_MemAlloc(REGISTRY_NAMELEN);
  320. LEAVE_DPSP();
  321. if(!lpszSPName)
  322. {
  323. DPF_ERR("Unable to allocate memory for sp name!");
  324. return E_OUTOFMEMORY;
  325. }
  326. // Open the registry key for the SP
  327. if(!FindSPInRegistry(lpguidSP, lpszSPName,REGISTRY_NAMELEN, &hkeySP))
  328. {
  329. DPF_ERR("Unable to find sp in registry!");
  330. hr = E_FAIL;
  331. goto CLEANUP_EXIT;
  332. }
  333. // Get the gateway value.
  334. if(!GetKeyValue(hkeySP, SZ_NATHELP, REG_SZ, &lpValue))
  335. {
  336. DPF(1, "Unable to get NATHelp key value from registry.");
  337. hr = E_FAIL;
  338. goto CLEANUP_EXIT;
  339. }
  340. dwSize = strlen(lpValue)+1;
  341. if(dwSize > cbszNATHelpDLL){
  342. DPF_ERR("Not enough room for NATHelp DLL path");
  343. goto CLEANUP_EXIT;
  344. }
  345. memcpy(lpszNATHelpDLL, lpValue, dwSize);
  346. // fall through
  347. CLEANUP_EXIT:
  348. if (lpszSPName) SP_MemFree(lpszSPName);
  349. if (lpValue) SP_MemFree(lpValue);
  350. // Close the Apps key
  351. if(hkeySP)
  352. RegCloseKey(hkeySP);
  353. return hr;
  354. } // GetNATHelpDLLFromRegistry
  355. #endif // USE_NATHELP