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.

468 lines
14 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name :
  4. acme.cpp
  5. Abstract:
  6. remove acme installed client files and acme registry keys
  7. Author:
  8. JoyC
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #define INITGUID
  13. #include "oleguid.h"
  14. #include "shlguid.h"
  15. #define DUCATI_REG_PREFIX _T("SOFTWARE\\Microsoft\\")
  16. #define DUCATI_SUBKEY _T("Terminal Server Client")
  17. #define DUCATI_RDPDRKEY _T("Default\\AddIns\\RDPDR")
  18. #define BITMAP_CACHE_FOLDER _T("Cache\\")
  19. #define BITMAP_CACHE_LOCATION _T("BitmapPersistCacheLocation")
  20. #define ADDIN_NAME _T("Name")
  21. //
  22. // Get the target path from a link file
  23. //
  24. BOOL GetLinkFileTarget(LPTSTR lpszLinkFile, LPTSTR lpszPath)
  25. {
  26. IShellLink* psl;
  27. TCHAR szPath[MAX_PATH];
  28. WIN32_FIND_DATA wfd;
  29. HRESULT hres;
  30. BOOL rc = FALSE;
  31. int cch;
  32. *lpszPath = 0; // assume failure
  33. // Get a pointer to the IShellLink interface.
  34. hres = CoCreateInstance(CLSID_ShellLink, NULL,
  35. CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl);
  36. if (SUCCEEDED(hres)) {
  37. IPersistFile* ppf;
  38. // Get a pointer to the IPersistFile interface.
  39. hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
  40. if (SUCCEEDED(hres)) {
  41. #ifndef UNICODE
  42. WCHAR wsz[MAX_PATH];
  43. // Ensure that the string is Unicode.
  44. cch = MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz,
  45. MAX_PATH);
  46. if (cch > 0) {
  47. // Load the shortcut.
  48. hres = ppf->Load(wsz, STGM_READ);
  49. #else
  50. // Load the shortcut.
  51. hres = ppf->Load(lpszLinkFile, STGM_READ);
  52. #endif
  53. if (SUCCEEDED(hres)) {
  54. // Get the path to the link target.
  55. hres = psl->GetPath(szPath,
  56. MAX_PATH, (WIN32_FIND_DATA *)&wfd,
  57. SLGP_SHORTPATH );
  58. if (SUCCEEDED(hres)) {
  59. lstrcpy(lpszPath, szPath);
  60. rc = TRUE;
  61. }
  62. }
  63. #ifndef UNICODE
  64. }
  65. #endif
  66. // Release the pointer to the IPersistFile interface.
  67. ppf->Release();
  68. ppf = NULL;
  69. }
  70. // Release the pointer to the IShellLink interface.
  71. psl->Release();
  72. psl = NULL;
  73. }
  74. return rc;
  75. }
  76. void DeleteProgramFiles(TCHAR * szProgramDirectory)
  77. {
  78. unsigned len;
  79. HANDLE hFile;
  80. WIN32_FIND_DATA FindFileData;
  81. len = _tcslen(szProgramDirectory);
  82. DBGMSG((_T("DeleteTSCFromStartMenu: TS Client: %s"), szProgramDirectory));
  83. //
  84. // Delete the folder
  85. //
  86. _tcscat(szProgramDirectory, _T("*.*"));
  87. hFile = FindFirstFile(szProgramDirectory, &FindFileData);
  88. if (hFile != INVALID_HANDLE_VALUE) {
  89. szProgramDirectory[len] = _T('\0');
  90. _tcscat(szProgramDirectory, FindFileData.cFileName);
  91. if (_tcscmp(FindFileData.cFileName, _T(".")) != 0 ||
  92. _tcscmp(FindFileData.cFileName, _T("..")) != 0) {
  93. DWORD dwFileAttributes;
  94. //
  95. // Remove the read only attribute for deleting
  96. //
  97. dwFileAttributes = GetFileAttributes(szProgramDirectory);
  98. dwFileAttributes &= ~(FILE_ATTRIBUTE_READONLY);
  99. SetFileAttributes(szProgramDirectory, dwFileAttributes);
  100. DBGMSG((_T("DeleteTSCFromStartMenu: delete: %s"), szProgramDirectory));
  101. DeleteFile(szProgramDirectory);
  102. }
  103. while(FindNextFile(hFile, &FindFileData)) {
  104. szProgramDirectory[len] = _T('\0');
  105. _tcscat(szProgramDirectory, FindFileData.cFileName);
  106. if (_tcscmp(FindFileData.cFileName, _T(".")) != 0 ||
  107. _tcscmp(FindFileData.cFileName, _T("..")) != 0) {
  108. DWORD dwFileAttributes;
  109. //
  110. // Remove the read only attribute for deleting
  111. //
  112. dwFileAttributes = GetFileAttributes(szProgramDirectory);
  113. dwFileAttributes &= ~(FILE_ATTRIBUTE_READONLY);
  114. SetFileAttributes(szProgramDirectory, dwFileAttributes);
  115. DBGMSG((_T("DeleteTSCFromStartMenu: delete: %s"), szProgramDirectory));
  116. DeleteFile(szProgramDirectory);
  117. }
  118. }
  119. FindClose(hFile);
  120. }
  121. //
  122. // Delete the directory
  123. //
  124. szProgramDirectory[len - 1] = _T('\0');
  125. RemoveDirectory(szProgramDirectory);
  126. }
  127. //
  128. // Delete the Terminal Server client entry from the Startup Menu
  129. //
  130. void DeleteTSCFromStartMenu(TCHAR* szProgmanPath)
  131. {
  132. TCHAR szBuf[MAX_PATH];
  133. LPITEMIDLIST ppidl = NULL;
  134. HINSTANCE hInstance = (HINSTANCE) NULL;
  135. HRESULT hres;
  136. DBGMSG((_T("DeleteTSCFromStartMenu")));
  137. //
  138. // Initialize the data
  139. //
  140. _tcscpy(szBuf, _T(""));
  141. //
  142. // Remove the tsclient folder under user's start menu folder.
  143. //
  144. hres = SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &ppidl);
  145. if(SUCCEEDED(hres))
  146. {
  147. unsigned len;
  148. HANDLE hFile;
  149. WIN32_FIND_DATA FindFileData;
  150. if (SHGetPathFromIDList(ppidl, szBuf)) {
  151. //
  152. // Delete Terminal Services Client folder in start menu
  153. //
  154. _tcscat(szBuf, _T("\\"));
  155. _tcscat(szBuf, szProgmanPath);
  156. _tcscat(szBuf, _T("\\"));
  157. len = _tcslen(szBuf);
  158. DBGMSG((_T("DeleteTSCFromStartMenu: TS Client: %s"), szBuf));
  159. //
  160. // Delete the folder
  161. //
  162. DeleteProgramFiles(szBuf);
  163. }
  164. else {
  165. DBGMSG((_T("DeleteTSCFromStartMenu: Failed to get program file path: gle: %d"),
  166. GetLastError()));
  167. }
  168. }
  169. else {
  170. DBGMSG((_T("DeleteTSCFromStartMenu: Failed to get program file location: (hres: 0x%x) gle:%d"),
  171. hres, GetLastError()));
  172. }
  173. //
  174. // Now remove the folder under start menu folder under all users (if any)
  175. //
  176. memset(&szBuf, 0x0, sizeof(szBuf));
  177. hres = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_PROGRAMS, &ppidl);
  178. if(SUCCEEDED(hres))
  179. {
  180. unsigned len;
  181. SHGetPathFromIDList(ppidl, szBuf);
  182. len = _tcslen(szBuf);
  183. //
  184. // Delete Terminal Services Client in common start menu
  185. //
  186. _tcscat(szBuf, _T("\\"));
  187. _tcscat(szBuf, szProgmanPath);
  188. _tcscat(szBuf, _T("\\"));
  189. DBGMSG((_T("DeleteTSCFromStartMenu: TS Client: %s"), szBuf));
  190. //
  191. // Delete the folder
  192. //
  193. DeleteProgramFiles(szBuf);
  194. }
  195. else {
  196. DBGMSG((_T("DeleteTSCFromStartMenu: Failed to get (common) program file location: hres=0x%x gle=%d"),
  197. hres,GetLastError()));
  198. }
  199. }
  200. //
  201. // Delete the Terminal Server client shortcuts from the desktop
  202. //
  203. void DeleteTSCDesktopShortcuts()
  204. {
  205. TCHAR szBuf[MAX_PATH];
  206. TCHAR szProgmanPath[MAX_PATH] = _T("");
  207. TCHAR szOldProgmanPath[MAX_PATH] = _T("");
  208. LPITEMIDLIST ppidl = NULL;
  209. SHFILEOPSTRUCT FileOp;
  210. HINSTANCE hInstance = (HINSTANCE) NULL;
  211. HRESULT hres, hInit;
  212. DBGMSG((_T("DeleteTSCDesktopShortcuts")));
  213. hInit = CoInitialize(NULL);
  214. _tcscpy(szBuf, _T(""));
  215. //
  216. // Find the desktop folder location
  217. //
  218. hres = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY , &ppidl);
  219. if(SUCCEEDED(hres))
  220. {
  221. HANDLE hFile;
  222. WIN32_FIND_DATA FindFileData;
  223. unsigned len;
  224. TCHAR szTarget[MAX_PATH];
  225. SHGetPathFromIDList(ppidl, szBuf);
  226. _tcscat(szBuf, _T("\\"));
  227. len = _tcslen(szBuf);
  228. DBGMSG((_T("DeleteTSCDesktopShortcuts: Desktop folder: %s"), szBuf));
  229. //
  230. // Enumerate each desktop file
  231. //
  232. _tcscat(szBuf, _T("*.lnk"));
  233. hFile = FindFirstFile(szBuf, &FindFileData);
  234. if (hFile != INVALID_HANDLE_VALUE) {
  235. szBuf[len] = _T('\0');
  236. _tcscat(szBuf, FindFileData.cFileName);
  237. //
  238. // Get the target of the shortcut link
  239. //
  240. if (GetLinkFileTarget(szBuf, szTarget)) {
  241. //
  242. // If the target points to mstsc.exe, then deletes the link
  243. //
  244. if (_tcsstr(szTarget, _T("mstsc.exe")) != NULL ||
  245. _tcsstr(szTarget, _T("MSTSC.EXE")) != NULL) {
  246. DWORD dwFileAttributes;
  247. //
  248. // Remove the read only attribute for deleting
  249. //
  250. dwFileAttributes = GetFileAttributes(szTarget);
  251. dwFileAttributes &= ~(FILE_ATTRIBUTE_READONLY);
  252. SetFileAttributes(szTarget, dwFileAttributes);
  253. DBGMSG((_T("DeleteTSCDesktopShortcuts: delete shortcuts: %s"), szBuf));
  254. DeleteFile(szBuf);
  255. }
  256. }
  257. while(FindNextFile(hFile, &FindFileData)) {
  258. szBuf[len] = _T('\0');
  259. _tcscat(szBuf, FindFileData.cFileName);
  260. // Get the target of the shortcut link
  261. if (GetLinkFileTarget(szBuf, szTarget)) {
  262. // If the target points to mstsc.exe, then deletes the link
  263. if (_tcsstr(szTarget, _T("mstsc.exe")) != NULL ||
  264. _tcsstr(szTarget, _T("MSTSC.EXE")) != NULL) {
  265. DWORD dwFileAttributes;
  266. //
  267. // Remove the read only attribute for deleting
  268. //
  269. dwFileAttributes = GetFileAttributes(szTarget);
  270. dwFileAttributes &= ~(FILE_ATTRIBUTE_READONLY);
  271. SetFileAttributes(szTarget, dwFileAttributes);
  272. DBGMSG((_T("DeleteTSCDesktopShortcuts: delete shortcuts: %s"), szBuf));
  273. DeleteFile(szBuf);
  274. }
  275. }
  276. }
  277. FindClose(hFile);
  278. }
  279. }
  280. else {
  281. DBGMSG((_T("DeleteTSCDesktopShortcuts: Failed to find desktop location: %d"),
  282. GetLastError()));
  283. }
  284. if (SUCCEEDED(hInit)) {
  285. CoUninitialize();
  286. }
  287. }
  288. //
  289. // Delete the bitmap cache folder
  290. //
  291. void DeleteBitmapCacheFolder(TCHAR *szDstDir)
  292. {
  293. TCHAR szCacheFolderName[2 * MAX_PATH] = _T("");
  294. TCHAR szRootPath[MAX_PATH] = _T("");
  295. DWORD lpcbData = MAX_PATH;
  296. SHFILEOPSTRUCT FileOp;
  297. DWORD dwSubSize = MAX_PATH;
  298. TCHAR szRegPath[MAX_PATH] = _T("");
  299. HKEY hKey = NULL;
  300. int nLen = 0;
  301. //
  302. // Delete the bitmap cache folder as specified in the registry.
  303. //
  304. _stprintf(szRegPath, _T("%s%s"), DUCATI_REG_PREFIX, DUCATI_SUBKEY);
  305. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, szRegPath, 0, KEY_READ, &hKey))
  306. {
  307. if (ERROR_SUCCESS == RegQueryValueEx(hKey, BITMAP_CACHE_LOCATION,
  308. NULL, NULL, (LPBYTE)szCacheFolderName, &lpcbData))
  309. {
  310. if (szCacheFolderName[0] != _T('\0'))
  311. {
  312. if (szCacheFolderName[lpcbData - 2] == _T('\\'))
  313. {
  314. szCacheFolderName[lpcbData - 2] = _T('\0');
  315. }
  316. //
  317. // Delete the bitmap cache folder.
  318. //
  319. memset(&FileOp, 0x0, sizeof(FileOp));
  320. FileOp.wFunc = FO_DELETE;
  321. FileOp.pFrom = szCacheFolderName;
  322. FileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
  323. SHFileOperation(&FileOp);
  324. }
  325. }
  326. RegCloseKey(hKey);
  327. }
  328. // Delete the default bitmap cache folder.
  329. if (szDstDir[0] == _T('\0'))
  330. {
  331. return ;
  332. }
  333. _stprintf(szCacheFolderName, _T("%s%s"), szDstDir, BITMAP_CACHE_FOLDER);
  334. if (szCacheFolderName[0] != '\0')
  335. {
  336. nLen = _tcslen(szCacheFolderName);
  337. if (szCacheFolderName[nLen - 1] == _T('\\'))
  338. {
  339. szCacheFolderName[nLen - 1] = _T('\0');
  340. }
  341. //
  342. //Delete the bitmap cache folder.
  343. //
  344. memset(&FileOp, 0x0, sizeof(FileOp));
  345. FileOp.wFunc = FO_DELETE;
  346. FileOp.pFrom = szCacheFolderName;
  347. FileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
  348. SHFileOperation(&FileOp);
  349. }
  350. return ;
  351. }
  352. //
  353. // Delete any registry key
  354. //
  355. void DeleteTSCRegKeys()
  356. {
  357. TCHAR szRegPath[MAX_PATH] = _T("");
  358. HKEY hKey = NULL;
  359. //
  360. // Delete the rdpdr dll VC Addin as specified in the registry.
  361. //
  362. _stprintf(szRegPath, _T("%s%s\\%s"), DUCATI_REG_PREFIX, DUCATI_SUBKEY, DUCATI_RDPDRKEY);
  363. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, szRegPath, 0, KEY_READ, &hKey))
  364. {
  365. DBGMSG((_T("DeleteTSCRegKeys: HKCU %s"), szRegPath));
  366. RegDeleteValue(hKey, ADDIN_NAME);
  367. RegCloseKey(hKey);
  368. RegDeleteKey(HKEY_CURRENT_USER, szRegPath);
  369. }
  370. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegPath, 0, KEY_READ, &hKey))
  371. {
  372. DBGMSG((_T("DeleteTSCRegKeys: HKLM %s"), szRegPath));
  373. RegDeleteValue(hKey, ADDIN_NAME);
  374. RegCloseKey(hKey);
  375. RegDeleteKey(HKEY_LOCAL_MACHINE, szRegPath);
  376. }
  377. }