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
240 lines
7.6 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
umrdpdrv.c
|
|
|
|
Abstract:
|
|
|
|
User-Mode Component for RDP Device Management that Handles Drive Device-
|
|
Specific tasks.
|
|
|
|
This is a supporting module. The main module is umrdpdr.c.
|
|
|
|
Author:
|
|
|
|
Joy Chik 2/1/2000
|
|
|
|
Revision History:
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
#include <rdpdr.h>
|
|
#include <winnetwk.h>
|
|
|
|
#include "umrdpdr.h"
|
|
#include "drdevlst.h"
|
|
#include "umrdpdrv.h"
|
|
#include "drdbg.h"
|
|
|
|
// Global debug flag.
|
|
extern DWORD GLOBAL_DEBUG_FLAGS;
|
|
extern WCHAR ProviderName[MAX_PATH];
|
|
|
|
BOOL
|
|
UMRDPDRV_HandleDriveAnnounceEvent(
|
|
IN PDRDEVLST installedDevices,
|
|
IN PRDPDR_DRIVEDEVICE_SUB pDriveAnnounce,
|
|
HANDLE TokenForLoggedOnUser
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handle a drive device announce event from the "dr" by
|
|
adding a record for the device to the list of installed devices.
|
|
|
|
Arguments:
|
|
|
|
installedDevices - Comprehensive device list.
|
|
pDriveAnnounce - Drive device announce event.
|
|
TokenForLoggedOnUser - user token
|
|
|
|
Return Value:
|
|
|
|
Return TRUE on success. FALSE, otherwise.
|
|
|
|
--*/
|
|
{
|
|
DWORD status;
|
|
BOOL fImpersonated;
|
|
BOOL result;
|
|
DWORD offset;
|
|
LPNETRESOURCEW NetResource;
|
|
WCHAR RemoteName[RDPDR_MAX_COMPUTER_NAME_LENGTH + 4 + RDPDR_MAX_DOSNAMELEN];
|
|
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_HandleDriveAnnounceEvent with clientName %ws.\n",
|
|
pDriveAnnounce->clientName));
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_HandleDriveAnnounceEvent with drive %ws.\n",
|
|
pDriveAnnounce->driveName));
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:Preferred DOS name is %s.\n",
|
|
pDriveAnnounce->deviceFields.PreferredDosName));
|
|
|
|
ASSERT((pDriveAnnounce->deviceFields.DeviceType == RDPDR_DTYP_FILESYSTEM));
|
|
ASSERT(TokenForLoggedOnUser != NULL);
|
|
ASSERT(ProviderName[0] != L'\0');
|
|
|
|
// We need to impersonate the logged on user
|
|
fImpersonated = ImpersonateLoggedOnUser(TokenForLoggedOnUser);
|
|
|
|
if (fImpersonated) {
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_HandleDriveAnnounceEvent userToken: %p fImpersonated : %d.\n",
|
|
TokenForLoggedOnUser, fImpersonated));
|
|
|
|
// Set up remote name in the format of \\clientname\drivename
|
|
// Note: We don't want : for the drivename
|
|
wcscpy(RemoteName, L"\\\\");
|
|
wcscat(RemoteName, pDriveAnnounce->clientName);
|
|
wcscat(RemoteName, L"\\");
|
|
wcscat(RemoteName, pDriveAnnounce->driveName);
|
|
if (RemoteName[wcslen(RemoteName) - 1] == L':') {
|
|
RemoteName[wcslen(RemoteName) - 1] = L'\0';
|
|
}
|
|
|
|
// Allocate the net resource struct
|
|
NetResource = (LPNETRESOURCEW) LocalAlloc(LPTR, sizeof(NETRESOURCEW));
|
|
|
|
if (NetResource) {
|
|
NetResource->dwScope = 0;
|
|
NetResource->lpLocalName = NULL;
|
|
NetResource->lpRemoteName = RemoteName;
|
|
NetResource->lpProvider = ProviderName;
|
|
|
|
status = WNetAddConnection2(NetResource, NULL, NULL, 0);
|
|
|
|
if ( status == NO_ERROR) {
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:Added drive connection %ws\n",
|
|
RemoteName));
|
|
result = TRUE;
|
|
}
|
|
else {
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:Failed to add drive connection %ws: %x\n",
|
|
RemoteName, status));
|
|
result = FALSE;
|
|
}
|
|
|
|
LocalFree(NetResource);
|
|
}
|
|
else {
|
|
DBGMSG(DBG_ERROR, ("UMRDPDRV:Failed to allocate NetResource\n"));
|
|
result = FALSE;
|
|
}
|
|
|
|
if (result) {
|
|
// Record the drive devices so that we can remove the connection
|
|
// on disconnect/logoff
|
|
result = DRDEVLST_Add(installedDevices,
|
|
pDriveAnnounce->deviceFields.DeviceId,
|
|
UMRDPDR_INVALIDSERVERDEVICEID,
|
|
pDriveAnnounce->deviceFields.DeviceType,
|
|
RemoteName,
|
|
pDriveAnnounce->driveName,
|
|
pDriveAnnounce->deviceFields.PreferredDosName
|
|
);
|
|
|
|
if (result) {
|
|
// Find the drive device in the devlist
|
|
result = DRDEVLST_FindByClientDeviceIDAndDeviceType(installedDevices,
|
|
pDriveAnnounce->deviceFields.DeviceId, pDriveAnnounce->deviceFields.DeviceType, &offset);
|
|
|
|
if (result) {
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:Create shell reg folder for %ws\n", RemoteName));
|
|
|
|
// Create shell reg folder for the drive connection
|
|
CreateDriveFolder(RemoteName, pDriveAnnounce->clientDisplayName,
|
|
&(installedDevices->devices[offset]));
|
|
}
|
|
else {
|
|
DBGMSG(DBG_ERROR, ("UMRDPDRV:Failed to find the device %ws in the devlist\n",
|
|
pDriveAnnounce->driveName));
|
|
WNetCancelConnection2(RemoteName, 0, TRUE);
|
|
}
|
|
}
|
|
else {
|
|
DBGMSG(DBG_ERROR, ("UMRDPDRV:Failed to add the device %ws to the devlist\n",
|
|
pDriveAnnounce->driveName));
|
|
WNetCancelConnection2(RemoteName, 0, TRUE);
|
|
}
|
|
}
|
|
|
|
// Revert the thread token to self
|
|
RevertToSelf();
|
|
}
|
|
else {
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_HandleDriveAnnounceEvent, impersonation failed\n"));
|
|
result = FALSE;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
UMRDPDRV_DeleteDriveConnection(
|
|
IN PDRDEVLSTENTRY deviceEntry,
|
|
HANDLE TokenForLoggedOnUser
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Delete drive device connection on disconnect / logoff
|
|
|
|
Arguments:
|
|
|
|
deviceEntry - Drive Device to be deleted
|
|
|
|
Return Value:
|
|
|
|
Return TRUE on success. FALSE, otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD status;
|
|
BOOL result;
|
|
BOOL fImpersonated;
|
|
WCHAR *szGuid;
|
|
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:Delete client drive connection %ws\n",
|
|
deviceEntry->serverDeviceName));
|
|
|
|
// We need to impersonate the logged on user
|
|
fImpersonated = ImpersonateLoggedOnUser(TokenForLoggedOnUser);
|
|
|
|
if (fImpersonated) {
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_DeleteDriveConnection userToken: %p fImpersonated : %d.\n",
|
|
TokenForLoggedOnUser, fImpersonated));
|
|
|
|
// Remove the drive UNC connection
|
|
status = WNetCancelConnection2(deviceEntry->serverDeviceName, 0, TRUE);
|
|
|
|
// Remove the shell reg folder
|
|
DeleteDriveFolder(deviceEntry);
|
|
|
|
if (status == NO_ERROR) {
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV: Deleted client drive connection %ws\n",
|
|
deviceEntry->serverDeviceName));
|
|
result = TRUE;
|
|
}
|
|
else {
|
|
DBGMSG(DBG_ERROR, ("UMRDPDRV: Failed to delete client drive connection %ws: %x\n",
|
|
deviceEntry->serverDeviceName, status));
|
|
result = FALSE;
|
|
}
|
|
|
|
// Revert the thread token to self
|
|
RevertToSelf();
|
|
}
|
|
else
|
|
{
|
|
DBGMSG(DBG_TRACE, ("UMRDPDRV:UMRDPDRV_DeleteDriveConnection, impersonation failed\n"));
|
|
result = FALSE;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|