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.

240 lines
7.6 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name :
  4. umrdpdrv.c
  5. Abstract:
  6. User-Mode Component for RDP Device Management that Handles Drive Device-
  7. Specific tasks.
  8. This is a supporting module. The main module is umrdpdr.c.
  9. Author:
  10. Joy Chik 2/1/2000
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #include <rdpdr.h>
  15. #include <winnetwk.h>
  16. #include "umrdpdr.h"
  17. #include "drdevlst.h"
  18. #include "umrdpdrv.h"
  19. #include "drdbg.h"
  20. // Global debug flag.
  21. extern DWORD GLOBAL_DEBUG_FLAGS;
  22. extern WCHAR ProviderName[MAX_PATH];
  23. BOOL
  24. UMRDPDRV_HandleDriveAnnounceEvent(
  25. IN PDRDEVLST installedDevices,
  26. IN PRDPDR_DRIVEDEVICE_SUB pDriveAnnounce,
  27. HANDLE TokenForLoggedOnUser
  28. )
  29. /*++
  30. Routine Description:
  31. Handle a drive device announce event from the "dr" by
  32. adding a record for the device to the list of installed devices.
  33. Arguments:
  34. installedDevices - Comprehensive device list.
  35. pDriveAnnounce - Drive device announce event.
  36. TokenForLoggedOnUser - user token
  37. Return Value:
  38. Return TRUE on success. FALSE, otherwise.
  39. --*/
  40. {
  41. DWORD status;
  42. BOOL fImpersonated;
  43. BOOL result;
  44. DWORD offset;
  45. LPNETRESOURCEW NetResource;
  46. WCHAR RemoteName[RDPDR_MAX_COMPUTER_NAME_LENGTH + 4 + RDPDR_MAX_DOSNAMELEN];
  47. DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_HandleDriveAnnounceEvent with clientName %ws.\n",
  48. pDriveAnnounce->clientName));
  49. DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_HandleDriveAnnounceEvent with drive %ws.\n",
  50. pDriveAnnounce->driveName));
  51. DBGMSG(DBG_TRACE, ("UMRDPDRV:Preferred DOS name is %s.\n",
  52. pDriveAnnounce->deviceFields.PreferredDosName));
  53. ASSERT((pDriveAnnounce->deviceFields.DeviceType == RDPDR_DTYP_FILESYSTEM));
  54. ASSERT(TokenForLoggedOnUser != NULL);
  55. ASSERT(ProviderName[0] != L'\0');
  56. // We need to impersonate the logged on user
  57. fImpersonated = ImpersonateLoggedOnUser(TokenForLoggedOnUser);
  58. if (fImpersonated) {
  59. DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_HandleDriveAnnounceEvent userToken: %p fImpersonated : %d.\n",
  60. TokenForLoggedOnUser, fImpersonated));
  61. // Set up remote name in the format of \\clientname\drivename
  62. // Note: We don't want : for the drivename
  63. wcscpy(RemoteName, L"\\\\");
  64. wcscat(RemoteName, pDriveAnnounce->clientName);
  65. wcscat(RemoteName, L"\\");
  66. wcscat(RemoteName, pDriveAnnounce->driveName);
  67. if (RemoteName[wcslen(RemoteName) - 1] == L':') {
  68. RemoteName[wcslen(RemoteName) - 1] = L'\0';
  69. }
  70. // Allocate the net resource struct
  71. NetResource = (LPNETRESOURCEW) LocalAlloc(LPTR, sizeof(NETRESOURCEW));
  72. if (NetResource) {
  73. NetResource->dwScope = 0;
  74. NetResource->lpLocalName = NULL;
  75. NetResource->lpRemoteName = RemoteName;
  76. NetResource->lpProvider = ProviderName;
  77. status = WNetAddConnection2(NetResource, NULL, NULL, 0);
  78. if ( status == NO_ERROR) {
  79. DBGMSG(DBG_TRACE, ("UMRDPDRV:Added drive connection %ws\n",
  80. RemoteName));
  81. result = TRUE;
  82. }
  83. else {
  84. DBGMSG(DBG_TRACE, ("UMRDPDRV:Failed to add drive connection %ws: %x\n",
  85. RemoteName, status));
  86. result = FALSE;
  87. }
  88. LocalFree(NetResource);
  89. }
  90. else {
  91. DBGMSG(DBG_ERROR, ("UMRDPDRV:Failed to allocate NetResource\n"));
  92. result = FALSE;
  93. }
  94. if (result) {
  95. // Record the drive devices so that we can remove the connection
  96. // on disconnect/logoff
  97. result = DRDEVLST_Add(installedDevices,
  98. pDriveAnnounce->deviceFields.DeviceId,
  99. UMRDPDR_INVALIDSERVERDEVICEID,
  100. pDriveAnnounce->deviceFields.DeviceType,
  101. RemoteName,
  102. pDriveAnnounce->driveName,
  103. pDriveAnnounce->deviceFields.PreferredDosName
  104. );
  105. if (result) {
  106. // Find the drive device in the devlist
  107. result = DRDEVLST_FindByClientDeviceIDAndDeviceType(installedDevices,
  108. pDriveAnnounce->deviceFields.DeviceId, pDriveAnnounce->deviceFields.DeviceType, &offset);
  109. if (result) {
  110. DBGMSG(DBG_TRACE, ("UMRDPDRV:Create shell reg folder for %ws\n", RemoteName));
  111. // Create shell reg folder for the drive connection
  112. CreateDriveFolder(RemoteName, pDriveAnnounce->clientDisplayName,
  113. &(installedDevices->devices[offset]));
  114. }
  115. else {
  116. DBGMSG(DBG_ERROR, ("UMRDPDRV:Failed to find the device %ws in the devlist\n",
  117. pDriveAnnounce->driveName));
  118. WNetCancelConnection2(RemoteName, 0, TRUE);
  119. }
  120. }
  121. else {
  122. DBGMSG(DBG_ERROR, ("UMRDPDRV:Failed to add the device %ws to the devlist\n",
  123. pDriveAnnounce->driveName));
  124. WNetCancelConnection2(RemoteName, 0, TRUE);
  125. }
  126. }
  127. // Revert the thread token to self
  128. RevertToSelf();
  129. }
  130. else {
  131. DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_HandleDriveAnnounceEvent, impersonation failed\n"));
  132. result = FALSE;
  133. }
  134. return result;
  135. }
  136. BOOL
  137. UMRDPDRV_DeleteDriveConnection(
  138. IN PDRDEVLSTENTRY deviceEntry,
  139. HANDLE TokenForLoggedOnUser
  140. )
  141. /*++
  142. Routine Description:
  143. Delete drive device connection on disconnect / logoff
  144. Arguments:
  145. deviceEntry - Drive Device to be deleted
  146. Return Value:
  147. Return TRUE on success. FALSE, otherwise.
  148. --*/
  149. {
  150. DWORD status;
  151. BOOL result;
  152. BOOL fImpersonated;
  153. WCHAR *szGuid;
  154. DBGMSG(DBG_TRACE, ("UMRDPDRV:Delete client drive connection %ws\n",
  155. deviceEntry->serverDeviceName));
  156. // We need to impersonate the logged on user
  157. fImpersonated = ImpersonateLoggedOnUser(TokenForLoggedOnUser);
  158. if (fImpersonated) {
  159. DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_DeleteDriveConnection userToken: %p fImpersonated : %d.\n",
  160. TokenForLoggedOnUser, fImpersonated));
  161. // Remove the drive UNC connection
  162. status = WNetCancelConnection2(deviceEntry->serverDeviceName, 0, TRUE);
  163. // Remove the shell reg folder
  164. DeleteDriveFolder(deviceEntry);
  165. if (status == NO_ERROR) {
  166. DBGMSG(DBG_TRACE, ("UMRDPDRV: Deleted client drive connection %ws\n",
  167. deviceEntry->serverDeviceName));
  168. result = TRUE;
  169. }
  170. else {
  171. DBGMSG(DBG_ERROR, ("UMRDPDRV: Failed to delete client drive connection %ws: %x\n",
  172. deviceEntry->serverDeviceName, status));
  173. result = FALSE;
  174. }
  175. // Revert the thread token to self
  176. RevertToSelf();
  177. }
  178. else
  179. {
  180. DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_DeleteDriveConnection, impersonation failed\n"));
  181. result = FALSE;
  182. }
  183. return result;
  184. }