Source code of Windows XP (NT5)
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.

427 lines
13 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. #include "resource.h"
  3. #include <nt.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. #include <windows.h>
  7. #include <assert.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <winreg.h>
  11. #include <wfregupg.h>
  12. #include <shlobj.h>
  13. #include <winioctl.h>
  14. #include <wchar.h>
  15. UINT WFMenuRemoveListMain[] = {
  16. IDS_WFSETUP,
  17. IDS_WFBOOKS,
  18. IDS_WFHELP,
  19. 0
  20. };
  21. UINT WFMenuRemoveListAdminTools[] = {
  22. IDS_NETWAREUSER,
  23. IDS_WFCDISKCREATOR,
  24. IDS_APPSECREG,
  25. 0
  26. };
  27. HINSTANCE g_hinst;
  28. UINT
  29. MyGetDriveType(
  30. IN TCHAR Drive
  31. )
  32. {
  33. TCHAR DriveNameNt[] = L"\\\\.\\?:";
  34. TCHAR DriveName[] = L"?:\\";
  35. HANDLE hDisk;
  36. BOOL b;
  37. UINT rc;
  38. DWORD DataSize;
  39. DISK_GEOMETRY MediaInfo;
  40. //
  41. // First, get the win32 drive type. If it tells us DRIVE_REMOVABLE,
  42. // then we need to see whether it's a floppy or hard disk. Otherwise
  43. // just believe the api.
  44. //
  45. DriveName[0] = Drive;
  46. if((rc = GetDriveType(DriveName)) == DRIVE_REMOVABLE) {
  47. DriveNameNt[4] = Drive;
  48. hDisk = CreateFile(
  49. DriveNameNt,
  50. FILE_READ_ATTRIBUTES,
  51. FILE_SHARE_READ | FILE_SHARE_WRITE,
  52. NULL,
  53. OPEN_EXISTING,
  54. 0,
  55. NULL
  56. );
  57. if(hDisk != INVALID_HANDLE_VALUE) {
  58. b = DeviceIoControl(
  59. hDisk,
  60. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  61. NULL,
  62. 0,
  63. &MediaInfo,
  64. sizeof(MediaInfo),
  65. &DataSize,
  66. NULL
  67. );
  68. //
  69. // It's really a hard disk if the media type is removable.
  70. //
  71. if(b && (MediaInfo.MediaType == RemovableMedia)) {
  72. rc = DRIVE_FIXED;
  73. }
  74. CloseHandle(hDisk);
  75. }
  76. }
  77. return(rc);
  78. }
  79. // this routine will look for shortcuts for selected apps on an upgraded WF system, and
  80. // if the drives have been remapped, the shortcuts will be removed and re-created.
  81. void CtxCleanupShortcuts()
  82. {
  83. HRESULT hResult;
  84. IUnknown *punk;
  85. IShellLink *pShellLink;
  86. IPersistFile *pFile;
  87. TCHAR szDeleteFile[MAX_PATH+1];
  88. TCHAR szSysDir[MAX_PATH+1];
  89. TCHAR szAccessoriesPath[MAX_PATH+1];
  90. TCHAR szMainPath[MAX_PATH+1];
  91. TCHAR szProfileDir[MAX_PATH+1];
  92. TCHAR szProfileName[MAX_PATH+1];
  93. TCHAR szSaveDir[MAX_PATH+1];
  94. TCHAR szShortcutFile[MAX_PATH+1];
  95. TCHAR szProgramPath[MAX_PATH+1];
  96. TCHAR szProgramName[MAX_PATH+1];
  97. TCHAR szProgramDescription[MAX_PATH+1];
  98. TCHAR szAdminName[MAX_PATH+1];
  99. int j;
  100. HKEY SourceKey;
  101. TCHAR drive = 'C';
  102. // now see if the drives were remapped - if so, we need to fix up some shortcuts-
  103. GetSystemDirectory(szSysDir,MAX_PATH);
  104. if(MyGetDriveType(drive) == DRIVE_FIXED) // drives not remapped
  105. return;
  106. // initialize some strings
  107. LoadString(g_hinst,IDS_ACCESSORIES_SUBPATH,szAccessoriesPath,MAX_PATH);
  108. LoadString(g_hinst,IDS_MAIN_SUBPATH,szMainPath,MAX_PATH);
  109. LoadString(g_hinst,IDS_PROFILES,szProfileName,MAX_PATH);
  110. LoadString(g_hinst,IDS_ADMINISTRATOR,szAdminName,MAX_PATH);
  111. GetEnvironmentVariable(L"SystemRoot",szProfileDir,MAX_PATH);
  112. wcscat(szProfileDir,L"\\");
  113. wcscat(szProfileDir,szProfileName);
  114. wcscat(szProfileDir,L"\\");
  115. wcscat(szProfileDir,szAdminName);
  116. // setup OLE stuff
  117. hResult = OleInitialize(NULL);
  118. hResult = CoCreateInstance(&CLSID_ShellLink,
  119. NULL,
  120. CLSCTX_SERVER,
  121. &IID_IUnknown,
  122. (void **)&punk);
  123. if (FAILED(hResult))
  124. goto done;
  125. hResult = punk->lpVtbl->QueryInterface(punk,&IID_IShellLink, (void **)&pShellLink);
  126. if (FAILED(hResult))
  127. goto done;
  128. hResult = punk->lpVtbl->QueryInterface(punk,&IID_IPersistFile, (void **)&pFile);
  129. if (FAILED(hResult))
  130. goto done;
  131. for(j = 1; j <= 4; j++)
  132. {
  133. //build up paths to .lnk files
  134. wcscpy(szDeleteFile,szProfileDir);
  135. wcscat(szDeleteFile,L"\\");
  136. switch(j) {
  137. case 1:
  138. wcscat(szDeleteFile,szAccessoriesPath);
  139. wcscat(szDeleteFile,L"\\");
  140. LoadString(g_hinst,IDS_ACCESSDESC1,szProgramDescription,MAX_PATH);
  141. LoadString(g_hinst,IDS_ACCESSPROG1,szProgramName,MAX_PATH);
  142. break;
  143. case 2:
  144. wcscat(szDeleteFile,szAccessoriesPath);
  145. wcscat(szDeleteFile,L"\\");
  146. LoadString(g_hinst,IDS_ACCESSDESC2,szProgramDescription,MAX_PATH);
  147. LoadString(g_hinst,IDS_ACCESSPROG2,szProgramName,MAX_PATH);
  148. break;
  149. case 3:
  150. wcscat(szDeleteFile,szMainPath);
  151. wcscat(szDeleteFile,L"\\");
  152. LoadString(g_hinst,IDS_MAINDESC1,szProgramDescription,MAX_PATH);
  153. LoadString(g_hinst,IDS_MAINPROG1,szProgramName,MAX_PATH);
  154. break;
  155. case 4:
  156. wcscat(szDeleteFile,szMainPath);
  157. wcscat(szDeleteFile,L"\\");
  158. LoadString(g_hinst,IDS_MAINDESC2,szProgramDescription,MAX_PATH);
  159. LoadString(g_hinst,IDS_MAINPROG2,szProgramName,MAX_PATH);
  160. break;
  161. }
  162. wcscat(szDeleteFile,szProgramDescription);
  163. wcscat(szDeleteFile,L".lnk");
  164. SetFileAttributes(szDeleteFile,FILE_ATTRIBUTE_NORMAL);
  165. // if we can't delete the original, then this user probably didn't have this
  166. // shortcut, or it's saved under a different file name. In either case we
  167. // don't want to create a new one.
  168. if(!DeleteFile(szDeleteFile))
  169. {
  170. continue;
  171. }
  172. // create new shortcut
  173. wcscpy(szProgramPath,szSysDir);
  174. wcscat(szProgramPath,L"\\");
  175. wcscat(szProgramPath,szProgramName);
  176. pShellLink->lpVtbl->SetPath(pShellLink,szProgramPath);
  177. pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,szSysDir);
  178. pShellLink->lpVtbl->SetDescription(pShellLink,szProgramDescription);
  179. // create the same file we deleted
  180. wcscpy(szShortcutFile,szDeleteFile);
  181. pFile->lpVtbl->Save(pFile,szShortcutFile,FALSE);
  182. }
  183. done:
  184. if (pFile != NULL)
  185. {
  186. pFile->lpVtbl->Release(pFile);
  187. pFile=NULL;
  188. }
  189. if (pShellLink != NULL)
  190. {
  191. pShellLink->lpVtbl->Release(pShellLink);
  192. pShellLink=NULL;
  193. }
  194. if (punk != NULL)
  195. {
  196. punk->lpVtbl->Release(punk);
  197. punk=NULL;
  198. }
  199. OleUninitialize();
  200. SetCurrentDirectory(szSaveDir);
  201. }
  202. /*
  203. * This function is used to remove items from the StartMenu that can't be removed via the
  204. * syssetup.inf interface. Items listed there under the StartMenu.ObjectsToDelete are deleted
  205. * the Default User\Start Menu directory (private items) or the All User\Start Menu directory
  206. * (common items). But many tools from WF 1.x are put in the Administrator\Start Menu.
  207. * This function will remove unwanted items from that group.
  208. */
  209. void CtxRemoveWFStartMenuItems()
  210. {
  211. TCHAR szProfileDir[MAX_PATH+1];
  212. TCHAR szProfileName[MAX_PATH+1];
  213. TCHAR szMainPath[MAX_PATH+1];
  214. TCHAR szAdminToolsPath[MAX_PATH+1];
  215. TCHAR szDeleteFile[MAX_PATH+1];
  216. TCHAR szSaveDir[MAX_PATH+1];
  217. TCHAR szTargetDir[MAX_PATH+1];
  218. TCHAR szAdminName[MAX_PATH+1];
  219. TCHAR szCurFile[MAX_PATH+1];
  220. int i;
  221. DWORD err;
  222. BOOL bWorking = TRUE;
  223. BOOL bFoundOne = FALSE;
  224. WIN32_FIND_DATA w32fileinfo;
  225. HANDLE hSearch;
  226. LoadString(g_hinst,IDS_MAIN_SUBPATH,szMainPath,MAX_PATH);
  227. LoadString(g_hinst,IDS_ADMINTOOLS_SUBPATH,szAdminToolsPath, MAX_PATH);
  228. LoadString(g_hinst,IDS_PROFILES,szProfileName,MAX_PATH);
  229. LoadString(g_hinst,IDS_ADMINISTRATOR,szAdminName,MAX_PATH);
  230. //build up a path to \StartMenu\Programs\Administrative Tools
  231. GetEnvironmentVariable(L"SystemRoot",szProfileDir,MAX_PATH);
  232. wcscat(szProfileDir,L"\\");
  233. wcscat(szProfileDir,szProfileName);
  234. wcscpy(szTargetDir,szProfileDir);
  235. wcscat(szTargetDir,L"\\");
  236. wcscat(szTargetDir,szAdminName);
  237. i=0;
  238. while(WFMenuRemoveListMain[i] != 0)
  239. {
  240. LoadString(g_hinst,WFMenuRemoveListMain[i],szCurFile,MAX_PATH);
  241. wcscpy(szDeleteFile,szTargetDir);
  242. wcscat(szDeleteFile,L"\\");
  243. wcscat(szDeleteFile,szMainPath);
  244. wcscat(szDeleteFile,L"\\");
  245. wcscat(szDeleteFile,szCurFile);
  246. wcscat(szDeleteFile,L".lnk");
  247. SetFileAttributes(szDeleteFile,FILE_ATTRIBUTE_NORMAL);
  248. DeleteFile(szDeleteFile);
  249. i++;
  250. }
  251. i=0;
  252. while(WFMenuRemoveListAdminTools[i] != 0)
  253. {
  254. LoadString(g_hinst,WFMenuRemoveListAdminTools[i],szCurFile,MAX_PATH);
  255. wcscpy(szDeleteFile,szTargetDir);
  256. wcscat(szDeleteFile,L"\\");
  257. wcscat(szDeleteFile,szAdminToolsPath);
  258. wcscat(szDeleteFile,L"\\");
  259. wcscat(szDeleteFile,szCurFile);
  260. wcscat(szDeleteFile,L".lnk");
  261. SetFileAttributes(szDeleteFile,FILE_ATTRIBUTE_NORMAL);
  262. DeleteFile(szDeleteFile);
  263. i++;
  264. }
  265. //if the admin tools directory is empty, delete it
  266. wcscat(szTargetDir,L"\\");
  267. wcscat(szTargetDir,szAdminToolsPath);
  268. GetCurrentDirectory(MAX_PATH,szSaveDir);
  269. if(!SetCurrentDirectory(szTargetDir))
  270. return;
  271. hSearch = FindFirstFile(L"*",&w32fileinfo);
  272. bWorking = TRUE;
  273. bFoundOne = FALSE;
  274. while(bWorking)
  275. {
  276. if( (!wcscmp(w32fileinfo.cFileName,L".")) ||
  277. (!wcscmp(w32fileinfo.cFileName,L"..")) )
  278. {
  279. bWorking = FindNextFile(hSearch,&w32fileinfo);
  280. continue;
  281. }
  282. else
  283. {
  284. bFoundOne = TRUE;
  285. break;
  286. }
  287. }
  288. FindClose(hSearch);
  289. SetCurrentDirectory(szProfileDir);
  290. if(!bFoundOne)
  291. RemoveDirectory(szTargetDir);
  292. SetCurrentDirectory(szSaveDir);
  293. return;
  294. }
  295. /***************************************************************************\
  296. * WinMain
  297. *
  298. * History:
  299. * 05-15-98 JasonL Created.
  300. \***************************************************************************/
  301. int WINAPI WinMain(
  302. HINSTANCE hInstance,
  303. HINSTANCE hPrevInstance,
  304. LPSTR lpszCmdParam,
  305. int nCmdShow)
  306. {
  307. HKEY CurKey;
  308. WCHAR szAppSetup[MAX_PATH+1];
  309. WCHAR szSystemDir[MAX_PATH+1];
  310. WCHAR szDeleteFile[MAX_PATH+1];
  311. WCHAR szWinLogonKey[MAX_PATH+1];
  312. WCHAR Data[MAX_PATH];
  313. DWORD size;
  314. PWCHAR pBegin, pEnd;
  315. WCHAR szNewData[MAX_PATH+1];
  316. WCHAR szTemp[MAX_PATH+1];
  317. WCHAR szAdministrator[MAX_PATH+1];
  318. WCHAR szUserName[MAX_PATH+1];
  319. long ret;
  320. WCHAR buf[MAX_PATH];
  321. // Load up some strings;
  322. g_hinst = hInstance;
  323. LoadString(g_hinst,IDS_WINLOGON_KEY,szWinLogonKey,MAX_PATH);
  324. LoadString(g_hinst,IDS_APPSETUP,szAppSetup,MAX_PATH);
  325. LoadString(g_hinst,IDS_ADMINISTRATOR,szAdministrator,MAX_PATH);
  326. size = sizeof(szUserName) / sizeof(WCHAR);
  327. // only run if it's the administrator - otherwise the directory won't have been created
  328. // yet
  329. if(!GetUserName(szUserName,&size))
  330. return 0;
  331. if(_wcsicmp(szUserName,szAdministrator) != 0)
  332. {
  333. return 0;
  334. }
  335. // only do the work if this is an upgraded WF system
  336. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,REG_CONTROL_CITRIX,0,KEY_ALL_ACCESS,&CurKey)
  337. == ERROR_SUCCESS)
  338. {
  339. RegCloseKey(CurKey);
  340. // call our workers ...
  341. CtxCleanupShortcuts();
  342. CtxRemoveWFStartMenuItems();
  343. }
  344. // then delete this file, and remove the entry in the AppSetup key
  345. GetSystemDirectory(szSystemDir,MAX_PATH);
  346. wcscpy(szDeleteFile,szSystemDir);
  347. wcscat(szDeleteFile,L"\\rmvlnks.exe");
  348. MoveFileEx(szDeleteFile,NULL,MOVEFILE_DELAY_UNTIL_REBOOT);
  349. return 0;
  350. }