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.

134 lines
4.0 KiB

  1. #include "priv.h"
  2. #include "advpub.h"
  3. #include "sdsutils.h"
  4. #include "utils.h"
  5. #ifndef ARRAYSIZE
  6. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  7. #endif
  8. /*----------------------------------------------------------
  9. Purpose: Behaves just like RegQueryValueEx, except if the
  10. data type is REG_EXPAND_SZ, then this goes ahead
  11. and expands out the string. *pdwType will always
  12. be massaged to REG_SZ if this happens.
  13. Returns:
  14. Cond: --
  15. */
  16. DWORD
  17. SDSQueryValueExA(
  18. IN HKEY hkey,
  19. IN LPCSTR pszValue,
  20. IN LPDWORD lpReserved,
  21. OUT LPDWORD pdwType,
  22. OUT LPVOID pvData,
  23. IN OUT LPDWORD pcbData)
  24. {
  25. DWORD dwRet;
  26. DWORD cbSize;
  27. DWORD dwType;
  28. LPSTR lpsz;
  29. if (pvData)
  30. {
  31. // Trying to get back data
  32. cbSize = *pcbData; // Size of output buffer
  33. dwRet = RegQueryValueExA(hkey, pszValue, lpReserved, &dwType,
  34. (LPBYTE)pvData, &cbSize);
  35. // Normally, we'd be done with this. But do some extra work
  36. // if this is an expandable string (something that has system
  37. // variables in it), or if we need to pad the buffer.
  38. if (NO_ERROR == dwRet)
  39. {
  40. // Note: on Win95, RegSetValueEx will always write the
  41. // full string out, including the null terminator. On NT,
  42. // it won't unless the write length was specified.
  43. // Hence, we have the following check.
  44. // Pad the buffer, in case the string didn't have a null
  45. // terminator when it was stored?
  46. if (REG_SZ == dwType)
  47. {
  48. // Yes
  49. if (cbSize < *pcbData)
  50. {
  51. LPSTR lpszData = (LPSTR)pvData;
  52. lpszData[cbSize] = '\0';
  53. }
  54. }
  55. // Expand the string?
  56. else if (REG_EXPAND_SZ == dwType)
  57. {
  58. // Yes
  59. // Use a temporary buffer to expand
  60. lpsz = (LPSTR)LocalAlloc(LPTR, *pcbData);
  61. if ( !lpsz )
  62. return ERROR_OUTOFMEMORY;
  63. cbSize = ExpandEnvironmentStringsA((LPSTR)pvData, lpsz, *pcbData);
  64. // BUGBUG:: NT screws up the cbSize returned...
  65. if (cbSize > 0)
  66. cbSize = lstrlen(lpsz) + 1;
  67. if (cbSize > 0 && cbSize <= *pcbData)
  68. lstrcpynA((LPSTR)pvData, lpsz, *pcbData);
  69. else
  70. dwRet = GetLastError();
  71. LocalFree(lpsz);
  72. // Massage dwType so that callers always see REG_SZ
  73. dwType = REG_SZ;
  74. }
  75. }
  76. }
  77. else
  78. {
  79. // Trying to find out how big of a buffer to use
  80. cbSize = 0;
  81. dwRet = RegQueryValueExA(hkey, pszValue, lpReserved, &dwType,
  82. NULL, &cbSize);
  83. if (NO_ERROR == dwRet && REG_EXPAND_SZ == dwType)
  84. {
  85. CHAR szBuff[1];
  86. // Find out the length of the expanded string
  87. //
  88. lpsz = (LPSTR)LocalAlloc(LPTR, cbSize);
  89. if (!lpsz)
  90. return ERROR_OUTOFMEMORY;
  91. dwRet = RegQueryValueExA(hkey, pszValue, lpReserved, NULL,
  92. (LPBYTE)lpsz, &cbSize);
  93. if (NO_ERROR == dwRet)
  94. {
  95. cbSize = ExpandEnvironmentStringsA(lpsz, szBuff, ARRAYSIZE(szBuff));
  96. // BUGBUG:: NT screws up the cbSize returned...
  97. if (cbSize > 0)
  98. cbSize = lstrlen(lpsz) + 1;
  99. }
  100. LocalFree(lpsz);
  101. // Massage dwType so that callers always see REG_SZ
  102. dwType = REG_SZ;
  103. }
  104. }
  105. if (pdwType)
  106. *pdwType = dwType;
  107. if (pcbData)
  108. *pcbData = cbSize;
  109. return dwRet;
  110. }