windows-nt/Source/XPSP1/NT/termsrv/admtools/rmvlnks/rmvlnks.c
2020-09-26 16:20:57 +08:00

428 lines
13 KiB
C

//Copyright (c) 1998 - 1999 Microsoft Corporation
#include "resource.h"
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <winreg.h>
#include <wfregupg.h>
#include <shlobj.h>
#include <winioctl.h>
#include <wchar.h>
UINT WFMenuRemoveListMain[] = {
IDS_WFSETUP,
IDS_WFBOOKS,
IDS_WFHELP,
0
};
UINT WFMenuRemoveListAdminTools[] = {
IDS_NETWAREUSER,
IDS_WFCDISKCREATOR,
IDS_APPSECREG,
0
};
HINSTANCE g_hinst;
UINT
MyGetDriveType(
IN TCHAR Drive
)
{
TCHAR DriveNameNt[] = L"\\\\.\\?:";
TCHAR DriveName[] = L"?:\\";
HANDLE hDisk;
BOOL b;
UINT rc;
DWORD DataSize;
DISK_GEOMETRY MediaInfo;
//
// First, get the win32 drive type. If it tells us DRIVE_REMOVABLE,
// then we need to see whether it's a floppy or hard disk. Otherwise
// just believe the api.
//
DriveName[0] = Drive;
if((rc = GetDriveType(DriveName)) == DRIVE_REMOVABLE) {
DriveNameNt[4] = Drive;
hDisk = CreateFile(
DriveNameNt,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(hDisk != INVALID_HANDLE_VALUE) {
b = DeviceIoControl(
hDisk,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&MediaInfo,
sizeof(MediaInfo),
&DataSize,
NULL
);
//
// It's really a hard disk if the media type is removable.
//
if(b && (MediaInfo.MediaType == RemovableMedia)) {
rc = DRIVE_FIXED;
}
CloseHandle(hDisk);
}
}
return(rc);
}
// this routine will look for shortcuts for selected apps on an upgraded WF system, and
// if the drives have been remapped, the shortcuts will be removed and re-created.
void CtxCleanupShortcuts()
{
HRESULT hResult;
IUnknown *punk;
IShellLink *pShellLink;
IPersistFile *pFile;
TCHAR szDeleteFile[MAX_PATH+1];
TCHAR szSysDir[MAX_PATH+1];
TCHAR szAccessoriesPath[MAX_PATH+1];
TCHAR szMainPath[MAX_PATH+1];
TCHAR szProfileDir[MAX_PATH+1];
TCHAR szProfileName[MAX_PATH+1];
TCHAR szSaveDir[MAX_PATH+1];
TCHAR szShortcutFile[MAX_PATH+1];
TCHAR szProgramPath[MAX_PATH+1];
TCHAR szProgramName[MAX_PATH+1];
TCHAR szProgramDescription[MAX_PATH+1];
TCHAR szAdminName[MAX_PATH+1];
int j;
HKEY SourceKey;
TCHAR drive = 'C';
// now see if the drives were remapped - if so, we need to fix up some shortcuts-
GetSystemDirectory(szSysDir,MAX_PATH);
if(MyGetDriveType(drive) == DRIVE_FIXED) // drives not remapped
return;
// initialize some strings
LoadString(g_hinst,IDS_ACCESSORIES_SUBPATH,szAccessoriesPath,MAX_PATH);
LoadString(g_hinst,IDS_MAIN_SUBPATH,szMainPath,MAX_PATH);
LoadString(g_hinst,IDS_PROFILES,szProfileName,MAX_PATH);
LoadString(g_hinst,IDS_ADMINISTRATOR,szAdminName,MAX_PATH);
GetEnvironmentVariable(L"SystemRoot",szProfileDir,MAX_PATH);
wcscat(szProfileDir,L"\\");
wcscat(szProfileDir,szProfileName);
wcscat(szProfileDir,L"\\");
wcscat(szProfileDir,szAdminName);
// setup OLE stuff
hResult = OleInitialize(NULL);
hResult = CoCreateInstance(&CLSID_ShellLink,
NULL,
CLSCTX_SERVER,
&IID_IUnknown,
(void **)&punk);
if (FAILED(hResult))
goto done;
hResult = punk->lpVtbl->QueryInterface(punk,&IID_IShellLink, (void **)&pShellLink);
if (FAILED(hResult))
goto done;
hResult = punk->lpVtbl->QueryInterface(punk,&IID_IPersistFile, (void **)&pFile);
if (FAILED(hResult))
goto done;
for(j = 1; j <= 4; j++)
{
//build up paths to .lnk files
wcscpy(szDeleteFile,szProfileDir);
wcscat(szDeleteFile,L"\\");
switch(j) {
case 1:
wcscat(szDeleteFile,szAccessoriesPath);
wcscat(szDeleteFile,L"\\");
LoadString(g_hinst,IDS_ACCESSDESC1,szProgramDescription,MAX_PATH);
LoadString(g_hinst,IDS_ACCESSPROG1,szProgramName,MAX_PATH);
break;
case 2:
wcscat(szDeleteFile,szAccessoriesPath);
wcscat(szDeleteFile,L"\\");
LoadString(g_hinst,IDS_ACCESSDESC2,szProgramDescription,MAX_PATH);
LoadString(g_hinst,IDS_ACCESSPROG2,szProgramName,MAX_PATH);
break;
case 3:
wcscat(szDeleteFile,szMainPath);
wcscat(szDeleteFile,L"\\");
LoadString(g_hinst,IDS_MAINDESC1,szProgramDescription,MAX_PATH);
LoadString(g_hinst,IDS_MAINPROG1,szProgramName,MAX_PATH);
break;
case 4:
wcscat(szDeleteFile,szMainPath);
wcscat(szDeleteFile,L"\\");
LoadString(g_hinst,IDS_MAINDESC2,szProgramDescription,MAX_PATH);
LoadString(g_hinst,IDS_MAINPROG2,szProgramName,MAX_PATH);
break;
}
wcscat(szDeleteFile,szProgramDescription);
wcscat(szDeleteFile,L".lnk");
SetFileAttributes(szDeleteFile,FILE_ATTRIBUTE_NORMAL);
// if we can't delete the original, then this user probably didn't have this
// shortcut, or it's saved under a different file name. In either case we
// don't want to create a new one.
if(!DeleteFile(szDeleteFile))
{
continue;
}
// create new shortcut
wcscpy(szProgramPath,szSysDir);
wcscat(szProgramPath,L"\\");
wcscat(szProgramPath,szProgramName);
pShellLink->lpVtbl->SetPath(pShellLink,szProgramPath);
pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,szSysDir);
pShellLink->lpVtbl->SetDescription(pShellLink,szProgramDescription);
// create the same file we deleted
wcscpy(szShortcutFile,szDeleteFile);
pFile->lpVtbl->Save(pFile,szShortcutFile,FALSE);
}
done:
if (pFile != NULL)
{
pFile->lpVtbl->Release(pFile);
pFile=NULL;
}
if (pShellLink != NULL)
{
pShellLink->lpVtbl->Release(pShellLink);
pShellLink=NULL;
}
if (punk != NULL)
{
punk->lpVtbl->Release(punk);
punk=NULL;
}
OleUninitialize();
SetCurrentDirectory(szSaveDir);
}
/*
* This function is used to remove items from the StartMenu that can't be removed via the
* syssetup.inf interface. Items listed there under the StartMenu.ObjectsToDelete are deleted
* the Default User\Start Menu directory (private items) or the All User\Start Menu directory
* (common items). But many tools from WF 1.x are put in the Administrator\Start Menu.
* This function will remove unwanted items from that group.
*/
void CtxRemoveWFStartMenuItems()
{
TCHAR szProfileDir[MAX_PATH+1];
TCHAR szProfileName[MAX_PATH+1];
TCHAR szMainPath[MAX_PATH+1];
TCHAR szAdminToolsPath[MAX_PATH+1];
TCHAR szDeleteFile[MAX_PATH+1];
TCHAR szSaveDir[MAX_PATH+1];
TCHAR szTargetDir[MAX_PATH+1];
TCHAR szAdminName[MAX_PATH+1];
TCHAR szCurFile[MAX_PATH+1];
int i;
DWORD err;
BOOL bWorking = TRUE;
BOOL bFoundOne = FALSE;
WIN32_FIND_DATA w32fileinfo;
HANDLE hSearch;
LoadString(g_hinst,IDS_MAIN_SUBPATH,szMainPath,MAX_PATH);
LoadString(g_hinst,IDS_ADMINTOOLS_SUBPATH,szAdminToolsPath, MAX_PATH);
LoadString(g_hinst,IDS_PROFILES,szProfileName,MAX_PATH);
LoadString(g_hinst,IDS_ADMINISTRATOR,szAdminName,MAX_PATH);
//build up a path to \StartMenu\Programs\Administrative Tools
GetEnvironmentVariable(L"SystemRoot",szProfileDir,MAX_PATH);
wcscat(szProfileDir,L"\\");
wcscat(szProfileDir,szProfileName);
wcscpy(szTargetDir,szProfileDir);
wcscat(szTargetDir,L"\\");
wcscat(szTargetDir,szAdminName);
i=0;
while(WFMenuRemoveListMain[i] != 0)
{
LoadString(g_hinst,WFMenuRemoveListMain[i],szCurFile,MAX_PATH);
wcscpy(szDeleteFile,szTargetDir);
wcscat(szDeleteFile,L"\\");
wcscat(szDeleteFile,szMainPath);
wcscat(szDeleteFile,L"\\");
wcscat(szDeleteFile,szCurFile);
wcscat(szDeleteFile,L".lnk");
SetFileAttributes(szDeleteFile,FILE_ATTRIBUTE_NORMAL);
DeleteFile(szDeleteFile);
i++;
}
i=0;
while(WFMenuRemoveListAdminTools[i] != 0)
{
LoadString(g_hinst,WFMenuRemoveListAdminTools[i],szCurFile,MAX_PATH);
wcscpy(szDeleteFile,szTargetDir);
wcscat(szDeleteFile,L"\\");
wcscat(szDeleteFile,szAdminToolsPath);
wcscat(szDeleteFile,L"\\");
wcscat(szDeleteFile,szCurFile);
wcscat(szDeleteFile,L".lnk");
SetFileAttributes(szDeleteFile,FILE_ATTRIBUTE_NORMAL);
DeleteFile(szDeleteFile);
i++;
}
//if the admin tools directory is empty, delete it
wcscat(szTargetDir,L"\\");
wcscat(szTargetDir,szAdminToolsPath);
GetCurrentDirectory(MAX_PATH,szSaveDir);
if(!SetCurrentDirectory(szTargetDir))
return;
hSearch = FindFirstFile(L"*",&w32fileinfo);
bWorking = TRUE;
bFoundOne = FALSE;
while(bWorking)
{
if( (!wcscmp(w32fileinfo.cFileName,L".")) ||
(!wcscmp(w32fileinfo.cFileName,L"..")) )
{
bWorking = FindNextFile(hSearch,&w32fileinfo);
continue;
}
else
{
bFoundOne = TRUE;
break;
}
}
FindClose(hSearch);
SetCurrentDirectory(szProfileDir);
if(!bFoundOne)
RemoveDirectory(szTargetDir);
SetCurrentDirectory(szSaveDir);
return;
}
/***************************************************************************\
* WinMain
*
* History:
* 05-15-98 JasonL Created.
\***************************************************************************/
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,
int nCmdShow)
{
HKEY CurKey;
WCHAR szAppSetup[MAX_PATH+1];
WCHAR szSystemDir[MAX_PATH+1];
WCHAR szDeleteFile[MAX_PATH+1];
WCHAR szWinLogonKey[MAX_PATH+1];
WCHAR Data[MAX_PATH];
DWORD size;
PWCHAR pBegin, pEnd;
WCHAR szNewData[MAX_PATH+1];
WCHAR szTemp[MAX_PATH+1];
WCHAR szAdministrator[MAX_PATH+1];
WCHAR szUserName[MAX_PATH+1];
long ret;
WCHAR buf[MAX_PATH];
// Load up some strings;
g_hinst = hInstance;
LoadString(g_hinst,IDS_WINLOGON_KEY,szWinLogonKey,MAX_PATH);
LoadString(g_hinst,IDS_APPSETUP,szAppSetup,MAX_PATH);
LoadString(g_hinst,IDS_ADMINISTRATOR,szAdministrator,MAX_PATH);
size = sizeof(szUserName) / sizeof(WCHAR);
// only run if it's the administrator - otherwise the directory won't have been created
// yet
if(!GetUserName(szUserName,&size))
return 0;
if(_wcsicmp(szUserName,szAdministrator) != 0)
{
return 0;
}
// only do the work if this is an upgraded WF system
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,REG_CONTROL_CITRIX,0,KEY_ALL_ACCESS,&CurKey)
== ERROR_SUCCESS)
{
RegCloseKey(CurKey);
// call our workers ...
CtxCleanupShortcuts();
CtxRemoveWFStartMenuItems();
}
// then delete this file, and remove the entry in the AppSetup key
GetSystemDirectory(szSystemDir,MAX_PATH);
wcscpy(szDeleteFile,szSystemDir);
wcscat(szDeleteFile,L"\\rmvlnks.exe");
MoveFileEx(szDeleteFile,NULL,MOVEFILE_DELAY_UNTIL_REBOOT);
return 0;
}