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.

119 lines
3.4 KiB

  1. //
  2. // REGDYKEY.C
  3. //
  4. // Copyright (C) Microsoft Corporation, 1995
  5. //
  6. // Implementation of RegCreateDynKey and supporting functions.
  7. //
  8. #include "pch.h"
  9. #ifdef WANT_DYNKEY_SUPPORT
  10. #ifdef VXD
  11. #pragma VxD_RARE_CODE_SEG
  12. #endif
  13. //
  14. // VMMRegCreateDynKey
  15. //
  16. // See VMM DDK of _RegCreateDynKey.
  17. //
  18. LONG
  19. REGAPI
  20. VMMRegCreateDynKey(
  21. LPCSTR lpKeyName,
  22. LPVOID KeyContext,
  23. PPROVIDER pProvider,
  24. PPVALUE pValueList,
  25. DWORD ValueCount,
  26. LPHKEY lphKey
  27. )
  28. {
  29. LONG ErrorCode;
  30. HKEY hKey;
  31. PINTERNAL_PROVIDER pProviderCopy;
  32. PPVALUE pCurrentValue;
  33. if (IsBadHugeReadPtr(pProvider, sizeof(REG_PROVIDER)) ||
  34. (IsNullPtr(pProvider-> pi_R0_1val) &&
  35. IsNullPtr(pProvider-> pi_R0_allvals)) ||
  36. IsBadHugeReadPtr(pValueList, sizeof(PVALUE) * ValueCount))
  37. return ERROR_INVALID_PARAMETER;
  38. if ((ErrorCode = RgCreateOrOpenKey(HKEY_DYN_DATA, lpKeyName, &hKey,
  39. LK_CREATE | LK_CREATEDYNDATA)) != ERROR_SUCCESS)
  40. return ErrorCode;
  41. if (!RgLockRegistry())
  42. ErrorCode = ERROR_LOCK_FAILED;
  43. else {
  44. pProviderCopy = RgSmAllocMemory(sizeof(INTERNAL_PROVIDER));
  45. if (IsNullPtr(pProviderCopy))
  46. ErrorCode = ERROR_OUTOFMEMORY;
  47. else {
  48. // ErrorCode = ERROR_SUCCESS; // Must be true if we're here...
  49. hKey-> pProvider = pProviderCopy;
  50. // If no "get single" callback was provided, we can just use the
  51. // "get atomic" callback.
  52. if (IsNullPtr(pProvider-> pi_R0_1val))
  53. pProviderCopy-> ipi_R0_1val = pProvider-> pi_R0_allvals;
  54. else
  55. pProviderCopy-> ipi_R0_1val = pProvider-> pi_R0_1val;
  56. pProviderCopy-> ipi_R0_allvals = pProvider-> pi_R0_allvals;
  57. pProviderCopy-> ipi_key_context = KeyContext;
  58. // No point in keeping a whole DWORD for one bit when we can fit
  59. // it inside the main key structure.
  60. if (pProvider-> pi_flags & PROVIDER_KEEPS_VALUE_LENGTH)
  61. hKey-> Flags |= KEYF_PROVIDERHASVALUELENGTH;
  62. // Loop over all the values and store each name in the registry
  63. // with a partial PVALUE record as the value's data.
  64. for (pCurrentValue = pValueList; ValueCount > 0; ValueCount--,
  65. pCurrentValue++) {
  66. if (IsBadStringPtr(pCurrentValue-> pv_valuename, (UINT) -1)) {
  67. ErrorCode = ERROR_INVALID_PARAMETER;
  68. break;
  69. }
  70. // Skip storing the pv_valuename field.
  71. if ((ErrorCode = RgSetValue(hKey, pCurrentValue-> pv_valuename,
  72. REG_BINARY, (LPBYTE) &(pCurrentValue-> pv_valuelen),
  73. sizeof(PVALUE) - FIELD_OFFSET(PVALUE, pv_valuename))) !=
  74. ERROR_SUCCESS) {
  75. TRAP();
  76. break;
  77. }
  78. }
  79. }
  80. RgUnlockRegistry();
  81. }
  82. // Win95 difference: on an error, don't modify lphKey and close the key
  83. // created above.
  84. if (ErrorCode == ERROR_SUCCESS)
  85. *lphKey = hKey;
  86. else
  87. VMMRegCloseKey(hKey);
  88. return ErrorCode;
  89. }
  90. #endif // WANT_DYNKEY_SUPPORT