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.

408 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name :
  4. drdevlst.c
  5. Abstract:
  6. Manage a list of installed devices for the user-mode RDP device manager
  7. component.
  8. Author:
  9. TadB
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #include "drdbg.h"
  15. #include "drdevlst.h"
  16. #include "errorlog.h"
  17. #include "tsnutl.h"
  18. #include <time.h>
  19. void
  20. DRDEVLST_Create(
  21. IN PDRDEVLST list
  22. )
  23. /*++
  24. Routine Description:
  25. Create a new device list.
  26. Arguments:
  27. list - Installed device list.
  28. Return Value:
  29. None
  30. --*/
  31. {
  32. list->devices = NULL;
  33. list->deviceCount = 0;
  34. list->listSize = 0;
  35. }
  36. void
  37. DRDEVLST_Destroy(
  38. IN PDRDEVLST list
  39. )
  40. /*++
  41. Routine Description:
  42. Destroy a device list. Note that the pointer to the list is not released.
  43. Arguments:
  44. list - Installed device list.
  45. Return Value:
  46. None
  47. --*/
  48. {
  49. ASSERT(list != NULL);
  50. if (list->devices != NULL) {
  51. #if DBG
  52. ASSERT(list->listSize > 0);
  53. memset(list->devices, DBG_GARBAGEMEM, list->listSize);
  54. #endif
  55. FREEMEM(list->devices);
  56. }
  57. #if DBG
  58. else {
  59. ASSERT(list->listSize == 0);
  60. }
  61. #endif
  62. list->listSize = 0;
  63. list->deviceCount = 0;
  64. list->devices = NULL;
  65. }
  66. BOOL DRDEVLST_Add(
  67. IN PDRDEVLST list,
  68. IN DWORD clientDeviceID,
  69. IN DWORD serverDeviceID,
  70. IN DWORD deviceType,
  71. IN PCWSTR serverDeviceName,
  72. IN PCWSTR clientDeviceName,
  73. IN PCSTR preferredDosName
  74. )
  75. /*++
  76. Routine Description:
  77. Add a device to a device management list.
  78. Arguments:
  79. list - Device list.
  80. clientDeviceID - ID for new device assigned by client component.
  81. serverDeviceID - ID for new device assigned by server component.
  82. deviceType - Is it a printer, etc.
  83. serverDeviceName - Server-designated device name.
  84. clientDeviceName - Client-designated device name.
  85. Return Value:
  86. Return TRUE on success. FALSE, otherwise.
  87. --*/
  88. {
  89. DWORD count;
  90. DWORD bytesRequired;
  91. DWORD len;
  92. BOOL result = TRUE;
  93. ASSERT(list != NULL);
  94. //
  95. // Size the device list if necessary.
  96. //
  97. bytesRequired = (list->deviceCount+1) * sizeof(DRDEVLSTENTRY);
  98. if (list->listSize < bytesRequired) {
  99. if (list->devices == NULL) {
  100. list->devices = ALLOCMEM(bytesRequired);
  101. }
  102. else {
  103. PDRDEVLSTENTRY pBuf = REALLOCMEM(list->devices, bytesRequired);
  104. if (pBuf != NULL) {
  105. list->devices = pBuf;
  106. } else {
  107. FREEMEM(list->devices);
  108. list->devices = NULL;
  109. list->deviceCount = 0;
  110. }
  111. }
  112. if (list->devices == NULL) {
  113. list->listSize = 0;
  114. }
  115. else {
  116. list->listSize = bytesRequired;
  117. }
  118. }
  119. //
  120. // Add the new device.
  121. //
  122. if (list->devices != NULL) {
  123. //
  124. // Allocate room for the variable-length string fields.
  125. //
  126. len = wcslen(serverDeviceName) + 1;
  127. list->devices[list->deviceCount].serverDeviceName =
  128. (WCHAR *)ALLOCMEM(len * sizeof(WCHAR));
  129. result = (list->devices[list->deviceCount].serverDeviceName != NULL);
  130. if (result) {
  131. len = wcslen(clientDeviceName) + 1;
  132. list->devices[list->deviceCount].clientDeviceName =
  133. (WCHAR *)ALLOCMEM(len * sizeof(WCHAR));
  134. result = (list->devices[list->deviceCount].clientDeviceName != NULL);
  135. //
  136. // Clean up the first alloc if we failed here.
  137. //
  138. if (!result) {
  139. FREEMEM(list->devices[list->deviceCount].serverDeviceName);
  140. list->devices[list->deviceCount].serverDeviceName = NULL;
  141. }
  142. }
  143. //
  144. // Copy the fields and add a timestamp for when the device was installed.
  145. //
  146. if (result) {
  147. wcscpy(list->devices[list->deviceCount].serverDeviceName, serverDeviceName);
  148. wcscpy(list->devices[list->deviceCount].clientDeviceName, clientDeviceName);
  149. strcpy(list->devices[list->deviceCount].preferredDosName, preferredDosName);
  150. list->devices[list->deviceCount].clientDeviceID = clientDeviceID;
  151. list->devices[list->deviceCount].serverDeviceID = serverDeviceID;
  152. list->devices[list->deviceCount].deviceType = deviceType;
  153. list->devices[list->deviceCount].fConfigInfoChanged = FALSE;
  154. list->devices[list->deviceCount].installTime = time(NULL);
  155. list->devices[list->deviceCount].deviceSpecificData = NULL;
  156. list->deviceCount++;
  157. }
  158. }
  159. else {
  160. result = FALSE;
  161. }
  162. if (!result) {
  163. //
  164. // Current failure scenarios are restricted to memory allocation failures.
  165. //
  166. TsLogError(EVENT_NOTIFY_INSUFFICIENTRESOURCES, EVENTLOG_ERROR_TYPE,
  167. 0, NULL, __LINE__);
  168. }
  169. return result;
  170. }
  171. void
  172. DRDEVLST_Remove(
  173. IN PDRDEVLST list,
  174. IN DWORD offset
  175. )
  176. /*++
  177. Routine Description:
  178. Remove the device at the specified offset.
  179. Arguments:
  180. list - Device list.
  181. offset - Offset of element in installed devices list.
  182. Return Value:
  183. None.
  184. --*/
  185. {
  186. DWORD toMove;
  187. ASSERT(list != NULL);
  188. ASSERT(offset < list->deviceCount);
  189. ASSERT(list->deviceCount > 0);
  190. ASSERT(list->devices[offset].deviceSpecificData == NULL);
  191. //
  192. // Release variable-length string fields.
  193. //
  194. if (list->devices[offset].serverDeviceName != NULL) {
  195. FREEMEM(list->devices[offset].serverDeviceName);
  196. }
  197. if (list->devices[offset].clientDeviceName != NULL) {
  198. FREEMEM(list->devices[offset].clientDeviceName);
  199. }
  200. //
  201. // Remove the deleted element.
  202. //
  203. if (offset < (list->deviceCount-1)) {
  204. toMove = list->deviceCount - offset - 1;
  205. memmove(&list->devices[offset], &list->devices[offset+1],
  206. sizeof(DRDEVLSTENTRY) * toMove);
  207. }
  208. list->deviceCount--;
  209. }
  210. BOOL
  211. DRDEVLST_FindByClientDeviceID(
  212. IN PDRDEVLST list,
  213. IN DWORD clientDeviceID,
  214. IN DWORD *ofs
  215. )
  216. /*++
  217. Routine Description:
  218. Returns the offset of the device with the specified client-assigned id.
  219. Arguments:
  220. list - Device list
  221. clientDeviceID - ID assigned by client for device to return.
  222. ofs - Offset of found element.
  223. Return Value:
  224. TRUE if the specified device is found. Otherwise, FALSE.
  225. --*/
  226. {
  227. ASSERT(list != NULL);
  228. for (*ofs=0; *ofs<list->deviceCount; (*ofs)++) {
  229. if (list->devices[*ofs].clientDeviceID == clientDeviceID)
  230. break;
  231. }
  232. return(*ofs<list->deviceCount);
  233. }
  234. BOOL
  235. DRDEVLST_FindByClientDeviceIDAndDeviceType(
  236. IN PDRDEVLST list,
  237. IN DWORD clientDeviceID,
  238. IN DWORD deviceType,
  239. IN DWORD *ofs
  240. )
  241. /*++
  242. Routine Description:
  243. Returns the offset of the device with the specified client-assigned id and device type.
  244. Arguments:
  245. list - Device list
  246. clientDeviceID - ID assigned by client for device to return.
  247. deviceType - Device Type
  248. ofs - Offset of found element.
  249. Return Value:
  250. TRUE if the specified device is found. Otherwise, FALSE.
  251. --*/
  252. {
  253. ASSERT(list != NULL);
  254. for (*ofs=0; *ofs<list->deviceCount; (*ofs)++) {
  255. if ((list->devices[*ofs].clientDeviceID == clientDeviceID) &&
  256. (list->devices[*ofs].deviceType == deviceType))
  257. break;
  258. }
  259. return(*ofs<list->deviceCount);
  260. }
  261. BOOL
  262. DRDEVLST_FindByServerDeviceID(
  263. IN PDRDEVLST list,
  264. IN DWORD serverDeviceID,
  265. IN DWORD *ofs
  266. )
  267. /*++
  268. Routine Description:
  269. Returns the offset of the device with the specified server-assigned id.
  270. Arguments:
  271. list - Device list
  272. serverDeviceID - ID assigned by server for device to return.
  273. ofs - Offset of found element.
  274. Return Value:
  275. TRUE if the specified device is found. Otherwise, FALSE.
  276. --*/
  277. {
  278. ASSERT(list != NULL);
  279. for (*ofs=0; *ofs<list->deviceCount; (*ofs)++) {
  280. if (list->devices[*ofs].serverDeviceID == serverDeviceID)
  281. break;
  282. }
  283. return(*ofs<list->deviceCount);
  284. }
  285. BOOL
  286. DRDEVLST_FindByServerDeviceName(
  287. IN PDRDEVLST list,
  288. IN PCWSTR serverDeviceName,
  289. IN DWORD *ofs
  290. )
  291. /*++
  292. Routine Description:
  293. Returns the offset of the device with the specified name.
  294. Arguments:
  295. list - Device list
  296. serverDeviceName - Server-designated device name of element to return.
  297. ofs - Offset of found element.
  298. Return Value:
  299. TRUE if the specified device is found. Otherwise, FALSE.
  300. --*/
  301. {
  302. ASSERT(list != NULL);
  303. for (*ofs=0; *ofs<list->deviceCount; (*ofs)++) {
  304. if (!wcscmp(list->devices[*ofs].serverDeviceName, serverDeviceName))
  305. break;
  306. }
  307. return(*ofs<list->deviceCount);
  308. }