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.

462 lines
11 KiB

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