Windows2003-3790/termsrv/notify/umrdpdrv.c

241 lines
7.6 KiB
C

/*++
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;
}