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.

341 lines
8.9 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. strtmenu.c
  5. Abstract:
  6. Routines to manipulate menu groups and items.
  7. Entry points:
  8. Author:
  9. Ted Miller (tedm) 5-Apr-1995
  10. Jaime Sasson (jaimes) 9-Aug-1995
  11. Revision History:
  12. Based on various other code that has been rewritten/modified
  13. many times by many people.
  14. --*/
  15. #include "setupp.h"
  16. #pragma hdrstop
  17. #if 0
  18. #define DDEDBG
  19. #ifdef DDEDBG
  20. #define DBGOUT(x) DbgOut x
  21. VOID
  22. DbgOut(
  23. IN PCSTR FormatString,
  24. ...
  25. )
  26. {
  27. CHAR Str[256];
  28. va_list arglist;
  29. wsprintfA(Str,"SETUP (%u): ",GetTickCount());
  30. OutputDebugStringA(Str);
  31. va_start(arglist,FormatString);
  32. wvsprintfA(Str,FormatString,arglist);
  33. va_end(arglist);
  34. OutputDebugStringA(Str);
  35. OutputDebugStringA("\n");
  36. }
  37. #else
  38. #define DBGOUT(x)
  39. #endif
  40. #endif
  41. BOOL
  42. RemoveMenuGroup(
  43. IN PCWSTR Group,
  44. IN BOOL CommonGroup
  45. )
  46. {
  47. return( DeleteGroup( Group, CommonGroup ) );
  48. }
  49. BOOL
  50. RemoveMenuItem(
  51. IN PCWSTR Group,
  52. IN PCWSTR Item,
  53. IN BOOL CommonGroup
  54. )
  55. {
  56. return( DeleteItem( Group, CommonGroup, Item, TRUE ) );
  57. }
  58. VOID
  59. DeleteMenuGroupsAndItems(
  60. IN HINF InfHandle
  61. )
  62. {
  63. INFCONTEXT InfContext;
  64. UINT LineCount,LineNo;
  65. PCWSTR SectionName = L"StartMenu.ObjectsToDelete";
  66. PCWSTR ObjectType;
  67. PCWSTR ObjectName;
  68. PCWSTR ObjectPath;
  69. PCWSTR GroupAttribute;
  70. BOOL CommonGroup;
  71. BOOL IsMenuItem;
  72. //
  73. // Get the number of lines in the section that contains the objects to
  74. // be deleted. The section may be empty or non-existant; this is not an
  75. // error condition.
  76. //
  77. LineCount = (UINT)SetupGetLineCount(InfHandle,SectionName);
  78. if((LONG)LineCount <= 0) {
  79. return;
  80. }
  81. for(LineNo=0; LineNo<LineCount; LineNo++) {
  82. if(SetupGetLineByIndex(InfHandle,SectionName,LineNo,&InfContext)
  83. && (ObjectType = pSetupGetField(&InfContext,1))
  84. && (ObjectName = pSetupGetField(&InfContext,2))
  85. && (GroupAttribute = pSetupGetField(&InfContext,4))) {
  86. IsMenuItem = _wtoi(ObjectType);
  87. CommonGroup = _wtoi(GroupAttribute);
  88. ObjectPath = pSetupGetField(&InfContext,3);
  89. if( IsMenuItem ) {
  90. RemoveMenuItem( ObjectPath, ObjectName, CommonGroup );
  91. } else {
  92. ULONG Size;
  93. PWSTR Path;
  94. Size = lstrlen(ObjectName) + 1;
  95. if(ObjectPath != NULL) {
  96. Size += lstrlen(ObjectPath) + 1;
  97. }
  98. Path = MyMalloc(Size * sizeof(WCHAR));
  99. if(!Path) {
  100. SetuplogError(
  101. LogSevError,
  102. SETUPLOG_USE_MESSAGEID,
  103. MSG_LOG_MENU_REMGRP_FAIL,
  104. ObjectPath,
  105. ObjectName, NULL,
  106. SETUPLOG_USE_MESSAGEID,
  107. MSG_LOG_OUTOFMEMORY,
  108. NULL,NULL);
  109. } else {
  110. if( ObjectPath != NULL ) {
  111. lstrcpy( Path, ObjectPath );
  112. pSetupConcatenatePaths( Path, ObjectName, Size, NULL );
  113. } else {
  114. lstrcpy( Path, ObjectName );
  115. }
  116. RemoveMenuGroup( Path, CommonGroup );
  117. MyFree(Path);
  118. }
  119. }
  120. }
  121. }
  122. }
  123. BOOL
  124. AddItemsToGroup(
  125. IN HINF InfHandle,
  126. IN PCWSTR GroupDescription,
  127. IN PCWSTR SectionName,
  128. IN BOOL CommonGroup
  129. )
  130. {
  131. INFCONTEXT InfContext;
  132. UINT LineCount,LineNo;
  133. PCWSTR Description;
  134. PCWSTR Binary;
  135. PCWSTR CommandLine;
  136. PCWSTR IconFile;
  137. PCWSTR IconNumberStr;
  138. INT IconNumber;
  139. PCWSTR InfoTip;
  140. BOOL b;
  141. BOOL DoItem;
  142. WCHAR Dummy;
  143. PWSTR FilePart;
  144. PCTSTR DisplayResourceFile = NULL;
  145. DWORD DisplayResource = 0;
  146. //
  147. // Get the number of lines in the section. The section may be empty
  148. // or non-existant; this is not an error condition.
  149. //
  150. LineCount = (UINT)SetupGetLineCount(InfHandle,SectionName);
  151. if((LONG)LineCount <= 0) {
  152. return(TRUE);
  153. }
  154. b = TRUE;
  155. for(LineNo=0; LineNo<LineCount; LineNo++) {
  156. if(SetupGetLineByIndex(InfHandle,SectionName,LineNo,&InfContext)) {
  157. Description = pSetupGetField(&InfContext,0);
  158. Binary = pSetupGetField(&InfContext,1);
  159. CommandLine = pSetupGetField(&InfContext,2);
  160. IconFile = pSetupGetField(&InfContext,3);
  161. IconNumberStr = pSetupGetField(&InfContext,4);
  162. InfoTip = pSetupGetField(&InfContext,5);
  163. DisplayResourceFile = pSetupGetField( &InfContext, 6);
  164. DisplayResource = 0;
  165. SetupGetIntField( &InfContext, 7, &DisplayResource );
  166. if(Description && CommandLine ) {
  167. if(!IconFile) {
  168. IconFile = L"";
  169. }
  170. IconNumber = (IconNumberStr && *IconNumberStr) ? wcstoul(IconNumberStr,NULL,10) : 0;
  171. //
  172. // If there's a binary name, search for it. Otherwise do the
  173. // item add unconditionally.
  174. //
  175. DoItem = (Binary && *Binary)
  176. ? (SearchPath(NULL,Binary,NULL,0,&Dummy,&FilePart) != 0)
  177. : TRUE;
  178. if(DoItem) {
  179. b &= CreateLinkFileEx( CommonGroup ? CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS,
  180. GroupDescription,
  181. Description,
  182. CommandLine,
  183. IconFile,
  184. IconNumber,
  185. NULL,
  186. 0,
  187. SW_SHOWNORMAL,
  188. InfoTip,
  189. (DisplayResourceFile && DisplayResourceFile[0]) ? DisplayResourceFile : NULL,
  190. (DisplayResourceFile && DisplayResourceFile[0]) ? DisplayResource : 0);
  191. }
  192. }
  193. }
  194. }
  195. return(b);
  196. }
  197. BOOL
  198. DoMenuGroupsAndItems(
  199. IN HINF InfHandle,
  200. IN BOOL Upgrade
  201. )
  202. {
  203. INFCONTEXT InfContext;
  204. PCWSTR GroupId,GroupDescription;
  205. PCWSTR GroupAttribute;
  206. BOOL CommonGroup;
  207. BOOL b;
  208. WCHAR Path[MAX_PATH+1];
  209. PCTSTR DisplayResourceFile = NULL;
  210. DWORD DisplayResource = 0;
  211. if( Upgrade ) {
  212. //
  213. // In the upgrade case, first delet some groups and items.
  214. //
  215. DeleteMenuGroupsAndItems( InfHandle );
  216. }
  217. //
  218. // Iterate the [StartMenuGroups] section in the inf.
  219. // Each line is the name of a group that needs to be created.
  220. //
  221. if(SetupFindFirstLine(InfHandle,L"StartMenuGroups",NULL,&InfContext)) {
  222. b = TRUE;
  223. } else {
  224. return(FALSE);
  225. }
  226. do {
  227. //
  228. // Fetch the identifier for the group and its name.
  229. //
  230. if((GroupId = pSetupGetField(&InfContext,0))
  231. && (GroupDescription = pSetupGetField(&InfContext,1))
  232. && (GroupAttribute = pSetupGetField(&InfContext,2))) {
  233. CommonGroup = ( GroupAttribute && _wtoi(GroupAttribute) );
  234. DisplayResourceFile = pSetupGetField( &InfContext, 3);
  235. DisplayResource = 0;
  236. SetupGetIntField( &InfContext, 4, &DisplayResource );
  237. //
  238. // Create the group.
  239. //
  240. b &= CreateGroupEx( GroupDescription, CommonGroup,
  241. (DisplayResourceFile && DisplayResourceFile[0]) ? DisplayResourceFile : NULL,
  242. (DisplayResourceFile && DisplayResourceFile[0]) ? DisplayResource : 0);
  243. //
  244. // Now create items within the group. We do this by iterating
  245. // through the section in the inf that relate to the current group.
  246. //
  247. b &= AddItemsToGroup(InfHandle,GroupDescription,GroupId,CommonGroup);
  248. }
  249. } while(SetupFindNextLine(&InfContext,&InfContext));
  250. //
  251. // Create the items (if any) for 'Start Menu'
  252. //
  253. b &= AddItemsToGroup(InfHandle,NULL,L"StartMenuItems",FALSE);
  254. return(TRUE);
  255. }
  256. BOOL
  257. CreateStartMenuItems(
  258. IN HINF InfHandle
  259. )
  260. {
  261. return(DoMenuGroupsAndItems(InfHandle,FALSE));
  262. }
  263. BOOL
  264. UpgradeStartMenuItems(
  265. IN HINF InfHandle
  266. )
  267. {
  268. return(DoMenuGroupsAndItems(InfHandle,TRUE));
  269. }
  270. BOOL
  271. RepairStartMenuItems(
  272. )
  273. {
  274. HINF InfHandle;
  275. BOOL b;
  276. //
  277. // This function is not called through Gui mode setup.
  278. // but is called by winlogon to repair stuff.
  279. //
  280. InitializeProfiles(FALSE);
  281. InfHandle = SetupOpenInfFile(L"syssetup.inf",NULL,INF_STYLE_WIN4,NULL);
  282. if( InfHandle == INVALID_HANDLE_VALUE ) {
  283. b = FALSE;
  284. } else {
  285. b = DoMenuGroupsAndItems(InfHandle,FALSE);
  286. SetupCloseInfFile(InfHandle);
  287. }
  288. return(b);
  289. }