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.

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