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.

274 lines
11 KiB

  1. /****************************************************************************/
  2. // acomapi.c
  3. //
  4. // RDP common functions API implemtation.
  5. //
  6. // Copyright (C) Microsoft, PictureTel 1992-1997
  7. // Copyright (C) 1997-2000 Microsoft Corporation
  8. /****************************************************************************/
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif /* __cplusplus */
  12. #include <precomp.h>
  13. #pragma hdrstop
  14. #define pTRCWd pTSWd
  15. #define TRC_FILE "acomapi"
  16. #include <adcg.h>
  17. #include <acomapi.h>
  18. #include <nwdwapi.h>
  19. #include <regapi.h>
  20. /****************************************************************************/
  21. /* Name: COM_OpenRegistry */
  22. /* */
  23. /* Purpose: Opens the given registry key relative to the WinStation */
  24. /* key name. Calls to COM_ReadProfxxx use the resulting handle. */
  25. /* */
  26. /* Returns: TRUE on success; FALSE otherwise */
  27. /* */
  28. /* Params: pTSWd - handle to WD data */
  29. /* pSection - name of section to open. This is appended to a */
  30. /* base key defined in the COM_MAKE_SUBKEY macro */
  31. /****************************************************************************/
  32. BOOL RDPCALL COM_OpenRegistry(PTSHARE_WD pTSWd, PWCHAR pSection)
  33. {
  34. NTSTATUS status;
  35. WCHAR subKey[MAX_PATH];
  36. BOOL rc = FALSE;
  37. UNICODE_STRING registryPath;
  38. OBJECT_ATTRIBUTES objAttribs;
  39. DC_BEGIN_FN("COM_OpenRegistry");
  40. /************************************************************************/
  41. /* Do some checks */
  42. /************************************************************************/
  43. TRC_ASSERT((sizeof(pTSWd->WinStationRegName) ==
  44. ((WINSTATIONNAME_LENGTH + 1) * sizeof(WCHAR))),
  45. (TB, "WinStationRegName doesn't appear to be Unicode"));
  46. TRC_ASSERT((pSection != NULL), (TB, "NULL pointer to section name"));
  47. /************************************************************************/
  48. /* Don't do this if someone has forgotten to close a key beforehand */
  49. /************************************************************************/
  50. if (!pTSWd->regAttemptedOpen) {
  51. // Construct the complete registry path.
  52. swprintf(subKey, L"\\Registry\\Machine\\%s\\%s\\%s",
  53. WINSTATION_REG_NAME, pTSWd->WinStationRegName, pSection);
  54. RtlInitUnicodeString(&registryPath, subKey);
  55. // Try to open the key.
  56. InitializeObjectAttributes(&objAttribs,
  57. &registryPath, // name
  58. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, // attributes
  59. NULL, // root
  60. NULL); // sec descriptor
  61. pTSWd->regAttemptedOpen = TRUE;
  62. status = ZwOpenKey(&(pTSWd->regKeyHandle),
  63. KEY_ALL_ACCESS,
  64. &objAttribs);
  65. if (status == STATUS_SUCCESS) {
  66. TRC_NRM((TB, "Opened key '%S'", subKey));
  67. rc = TRUE;
  68. }
  69. else {
  70. // The subkey probably doesn't exist.
  71. TRC_ALT((TB, "Couldn't open key '%S', rc = 0x%lx", subKey, status));
  72. pTSWd->regKeyHandle = NULL;
  73. }
  74. }
  75. else {
  76. TRC_ERR((TB, "COM_OpenRegistry called twice "
  77. "without calling COM_CloseRegistry"));
  78. }
  79. DC_END_FN();
  80. return rc;
  81. } /* COM_OpenRegistry */
  82. /****************************************************************************/
  83. /* Name: COM_CloseRegistry */
  84. /* */
  85. /* Purpose: Closes registry key that was opened with COM_OpenRegistry */
  86. /****************************************************************************/
  87. void RDPCALL COM_CloseRegistry(PTSHARE_WD pTSWd)
  88. {
  89. NTSTATUS status;
  90. DC_BEGIN_FN("COM_CloseRegistry");
  91. if (pTSWd->regAttemptedOpen)
  92. {
  93. /********************************************************************/
  94. /* Close the registry only if our original open was successful */
  95. /********************************************************************/
  96. if (pTSWd->regKeyHandle != NULL)
  97. {
  98. status = ZwClose(pTSWd->regKeyHandle);
  99. if (status != STATUS_SUCCESS)
  100. {
  101. TRC_ERR((TB, "Error closing registry key, rc = 0x%lx", status));
  102. }
  103. pTSWd->regKeyHandle = NULL;
  104. }
  105. else
  106. {
  107. TRC_NRM((TB, "Not closing key because open wasn't successful"));
  108. }
  109. pTSWd->regAttemptedOpen = FALSE;
  110. }
  111. else
  112. {
  113. TRC_ERR((TB, "Tried to close registry without opening it"));
  114. }
  115. DC_END_FN();
  116. } /* COM_CloseRegistry */
  117. /****************************************************************************/
  118. /* Name: COM_ReadProfInt32 */
  119. /* */
  120. /* Purpose: Reads a named value from the registry section opened */
  121. /* previously with COM_OpenRegistry */
  122. /* */
  123. /* Params: pTSWd - pointer to WD data structure */
  124. /* pEntry - name of value to read */
  125. /* defaultValue - default to return if there's a problem */
  126. /* pValue - pointer to memory in which to return the value */
  127. /****************************************************************************/
  128. void RDPCALL COM_ReadProfInt32(PTSHARE_WD pTSWd,
  129. PWCHAR pEntry,
  130. INT32 defaultValue,
  131. long *pValue)
  132. {
  133. NTSTATUS Status;
  134. DC_BEGIN_FN("COM_ReadProfInt32");
  135. /************************************************************************/
  136. /* Check for NULL parameters */
  137. /************************************************************************/
  138. TRC_ASSERT((pEntry != NULL), (TB, "NULL pointer to entry name"));
  139. /************************************************************************/
  140. /* Read the profile entry. */
  141. /************************************************************************/
  142. Status = COMReadEntry(pTSWd, pEntry, (PVOID)pValue, sizeof(INT32),
  143. REG_DWORD);
  144. if (Status != STATUS_SUCCESS) {
  145. /********************************************************************/
  146. /* We failed to read the value - copy in the default */
  147. /********************************************************************/
  148. TRC_NRM((TB, "Failed to read int32 from '%S'. Using default.",
  149. pEntry));
  150. *pValue = defaultValue;
  151. }
  152. TRC_NRM((TB, "Returning '%S' = %lu (0x%lx)",
  153. pEntry, *pValue, *pValue));
  154. DC_END_FN();
  155. } /* COM_ReadProfInt32 */
  156. /****************************************************************************/
  157. /* FUNCTION: COMReadEntry(...) */
  158. /* */
  159. /* Read an entry from the given section of the registry. Allow type */
  160. /* REG_BINARY (4 bytes) if REG_DWORD was requested. */
  161. /* */
  162. /* PARAMETERS: */
  163. /* pEntry : the entry name to read. */
  164. /* pBuffer : a buffer to read the entry to. */
  165. /* bufferSize : the size of the buffer. */
  166. /* expectedDataType : the type of data stored in the entry. */
  167. /****************************************************************************/
  168. NTSTATUS RDPCALL COMReadEntry(PTSHARE_WD pTSWd,
  169. PWCHAR pEntry,
  170. PVOID pBuffer,
  171. unsigned bufferSize,
  172. UINT32 expectedDataType)
  173. {
  174. NTSTATUS rc;
  175. UNICODE_STRING valueName;
  176. UINT32 keyInfoBuffer[16];
  177. PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
  178. ULONG keyInfoLength;
  179. DC_BEGIN_FN("COMReadEntry");
  180. /************************************************************************/
  181. /* Can't do much if the registry isn't open */
  182. /************************************************************************/
  183. if (pTSWd->regAttemptedOpen && pTSWd->regKeyHandle != NULL) {
  184. // Try to read the value. It may not exist.
  185. pKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)keyInfoBuffer;
  186. RtlInitUnicodeString(&valueName, pEntry);
  187. rc = ZwQueryValueKey(pTSWd->regKeyHandle,
  188. &valueName,
  189. KeyValuePartialInformation,
  190. pKeyInfo,
  191. sizeof(keyInfoBuffer),
  192. &keyInfoLength);
  193. if (rc != STATUS_SUCCESS) {
  194. TRC_DBG((TB, "Couldn't read key '%S', rc = 0x%lx",
  195. pEntry, rc));
  196. DC_QUIT;
  197. }
  198. // Check there's enough buffer space for the value.
  199. if (pKeyInfo->DataLength <= bufferSize) {
  200. // Check that the type is correct. Special case: allow REG_BINARY
  201. // instead of REG_DWORD, as long as the length is 32 bits.
  202. if ((pKeyInfo->Type == expectedDataType) ||
  203. (pKeyInfo->Type == REG_BINARY &&
  204. expectedDataType == REG_DWORD &&
  205. pKeyInfo->DataLength != 4)) {
  206. memcpy(pBuffer, pKeyInfo->Data, pKeyInfo->DataLength);
  207. }
  208. else {
  209. TRC_ALT((TB, "Read value from %S, but type is %u - expected %u",
  210. pEntry,
  211. pKeyInfo->Type,
  212. expectedDataType));
  213. rc = STATUS_DATA_ERROR;
  214. }
  215. }
  216. else {
  217. TRC_ERR((TB, "Not enough buffer space (%u) for value (%lu)",
  218. bufferSize,
  219. pKeyInfo->DataLength));
  220. rc = STATUS_BUFFER_OVERFLOW;
  221. }
  222. }
  223. else {
  224. if (!pTSWd->regAttemptedOpen)
  225. TRC_ERR((TB, "Tried to read from registry without opening it"));
  226. rc = STATUS_INVALID_HANDLE;
  227. }
  228. DC_EXIT_POINT:
  229. DC_END_FN();
  230. return rc;
  231. } /* COMReadEntry */
  232. #ifdef __cplusplus
  233. }
  234. #endif /* __cplusplus */