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.

469 lines
12 KiB

  1. /*++
  2. Copyright (c) 1998 Intel Corporation
  3. Module Name:
  4. protid.c
  5. Abstract:
  6. Shell environment variable management
  7. Revision History
  8. --*/
  9. #include "shelle.h"
  10. /*
  11. * The different variable catagories
  12. */
  13. LIST_ENTRY SEnvEnv;
  14. LIST_ENTRY SEnvMap;
  15. LIST_ENTRY SEnvAlias;
  16. VOID
  17. SEnvInitVariables (
  18. VOID
  19. )
  20. {
  21. CHAR16 *Name;
  22. CHAR16 *Data;
  23. UINTN BufferSize;
  24. UINTN NameSize, DataSize;
  25. EFI_GUID Id;
  26. LIST_ENTRY *ListHead;
  27. VARIABLE_ID *Var;
  28. EFI_STATUS Status;
  29. BOOLEAN IsString;
  30. UINT32 Attributes;
  31. UINTN Size;
  32. /*
  33. * Initialize the different variable lists
  34. */
  35. InitializeListHead (&SEnvEnv);
  36. InitializeListHead (&SEnvMap);
  37. InitializeListHead (&SEnvAlias);
  38. BufferSize = 1024;
  39. Name = AllocatePool (BufferSize);
  40. Data = AllocatePool (BufferSize);
  41. ASSERT(Name && Data);
  42. /*
  43. * Read all the variables in the system and collect ours
  44. */
  45. Name[0] = 0;
  46. for (; ;) {
  47. NameSize = BufferSize;
  48. Status = RT->GetNextVariableName (&NameSize, Name, &Id);
  49. if (EFI_ERROR(Status)) {
  50. break;
  51. }
  52. /*
  53. * See if it's a shellenv variable
  54. */
  55. ListHead = NULL;
  56. IsString = FALSE;
  57. if (CompareGuid (&Id, &SEnvEnvId) == 0) {
  58. ListHead = &SEnvEnv;
  59. IsString = TRUE;
  60. }
  61. if (CompareGuid (&Id, &SEnvMapId) == 0) {
  62. ListHead = &SEnvMap;
  63. }
  64. if (CompareGuid (&Id, &SEnvAliasId) == 0) {
  65. ListHead = &SEnvAlias;
  66. IsString = TRUE;
  67. }
  68. if (ListHead) {
  69. DataSize = BufferSize;
  70. Status = RT->GetVariable (Name, &Id, &Attributes, &DataSize, Data);
  71. if (!EFI_ERROR(Status)) {
  72. /*
  73. * Add this value
  74. */
  75. Size = sizeof(VARIABLE_ID) + StrSize(Name) + DataSize;
  76. Var = AllocateZeroPool (Size);
  77. Var->Signature = VARIABLE_SIGNATURE;
  78. Var->u.Value = ((UINT8 *) Var) + sizeof(VARIABLE_ID);
  79. Var->Name = (CHAR16*) (Var->u.Value + DataSize);
  80. Var->ValueSize = DataSize;
  81. CopyMem (Var->u.Value, Data, DataSize);
  82. CopyMem (Var->Name, Name, NameSize);
  83. if( Attributes & EFI_VARIABLE_NON_VOLATILE ) {
  84. Var->Flags = NON_VOL ;
  85. }
  86. else {
  87. Var->Flags = VOL ;
  88. }
  89. InsertTailList (ListHead, &Var->Link);
  90. }
  91. }
  92. /*
  93. * If this is a protocol entry, add it
  94. */
  95. if (CompareGuid (&Id, &SEnvProtId) == 0) {
  96. DataSize = BufferSize;
  97. Status = RT->GetVariable (Name, &Id, &Attributes, &DataSize, Data);
  98. if (!EFI_ERROR(Status) && DataSize == sizeof (EFI_GUID)) {
  99. SEnvIAddProtocol (FALSE, (EFI_GUID *) Data, NULL, NULL, Name);
  100. } else {
  101. DEBUG ((D_INIT|D_WARN, "SEnvInitVariables: skipping bogus protocol id %s\n", Var->Name));
  102. RT->SetVariable (Name, &SEnvProtId, 0, 0, NULL);
  103. }
  104. }
  105. }
  106. FreePool (Name);
  107. FreePool (Data);
  108. }
  109. CHAR16 *
  110. SEnvIGetStr (
  111. IN CHAR16 *Name,
  112. IN LIST_ENTRY *Head
  113. )
  114. {
  115. LIST_ENTRY *Link;
  116. VARIABLE_ID *Var;
  117. CHAR16 *Value;
  118. AcquireLock (&SEnvLock);
  119. Value = NULL;
  120. for (Link=Head->Flink; Link != Head; Link=Link->Flink) {
  121. Var = CR(Link, VARIABLE_ID, Link, VARIABLE_SIGNATURE);
  122. if (StriCmp (Var->Name, Name) == 0) {
  123. Value = Var->u.Str;
  124. break;
  125. }
  126. }
  127. ReleaseLock (&SEnvLock);
  128. return Value;
  129. }
  130. CHAR16 *
  131. SEnvGetMap (
  132. IN CHAR16 *Name
  133. )
  134. {
  135. return SEnvIGetStr (Name, &SEnvMap);
  136. }
  137. CHAR16 *
  138. SEnvGetEnv (
  139. IN CHAR16 *Name
  140. )
  141. {
  142. return SEnvIGetStr (Name, &SEnvEnv);
  143. }
  144. CHAR16 *
  145. SEnvGetAlias (
  146. IN CHAR16 *Name
  147. )
  148. {
  149. return SEnvIGetStr (Name, &SEnvAlias);
  150. }
  151. VOID
  152. SEnvSortVarList (
  153. IN LIST_ENTRY *Head
  154. )
  155. {
  156. ASSERT_LOCKED(&SEnvLock);
  157. return ;
  158. }
  159. EFI_STATUS
  160. SEnvCmdSA (
  161. IN EFI_HANDLE ImageHandle,
  162. IN EFI_SYSTEM_TABLE *SystemTable,
  163. IN LIST_ENTRY *Head,
  164. IN EFI_GUID *Guid
  165. )
  166. /* Code for shell "set" & "alias" command */
  167. {
  168. LIST_ENTRY *Link;
  169. VARIABLE_ID *Var;
  170. VARIABLE_ID *Found;
  171. CHAR16 *Name;
  172. CHAR16 *Value;
  173. UINTN Size, SLen, Len;
  174. BOOLEAN Delete;
  175. EFI_STATUS Status;
  176. UINTN Index;
  177. CHAR16 *p;
  178. BOOLEAN PageBreaks;
  179. UINTN TempColumn;
  180. UINTN ScreenCount;
  181. UINTN ScreenSize;
  182. CHAR16 ReturnStr[1];
  183. BOOLEAN Volatile;
  184. InitializeShellApplication (ImageHandle, SystemTable);
  185. Name = NULL;
  186. Value = NULL;
  187. Delete = FALSE;
  188. Status = EFI_SUCCESS;
  189. Found = NULL;
  190. Volatile = FALSE;
  191. /*
  192. * Crack arguments
  193. */
  194. PageBreaks = FALSE;
  195. for (Index = 1; Index < SI->Argc; Index += 1) {
  196. p = SI->Argv[Index];
  197. if (*p == '-') {
  198. switch (p[1]) {
  199. case 'd':
  200. case 'D':
  201. Delete = TRUE;
  202. break;
  203. case 'b' :
  204. case 'B' :
  205. PageBreaks = TRUE;
  206. ST->ConOut->QueryMode (ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
  207. ScreenCount = 0;
  208. break;
  209. case 'v' :
  210. case 'V' :
  211. Volatile = TRUE;
  212. break;
  213. default:
  214. Print (L"%ESet/Alias: Unknown flag %s\n", p);
  215. return EFI_INVALID_PARAMETER;
  216. }
  217. continue;
  218. }
  219. if (!Name) {
  220. Name = p;
  221. continue;
  222. }
  223. if (!Value) {
  224. Value = p;
  225. continue;
  226. }
  227. Print (L"%ESet/Alias: too many arguments\n");
  228. return EFI_INVALID_PARAMETER;
  229. }
  230. if (Delete && Value) {
  231. Print (L"%ESet/Alias: too many arguments\n");
  232. }
  233. /*
  234. * Process
  235. */
  236. AcquireLock (&SEnvLock);
  237. if (!Name) {
  238. /* dump the list */
  239. SEnvSortVarList (Head);
  240. SLen = 0;
  241. for (Link=Head->Flink; Link != Head; Link=Link->Flink) {
  242. Var = CR(Link, VARIABLE_ID, Link, VARIABLE_SIGNATURE);
  243. Len = StrLen(Var->Name);
  244. if (Len > SLen) {
  245. SLen = Len;
  246. }
  247. }
  248. for (Link=Head->Flink; Link != Head; Link=Link->Flink) {
  249. Var = CR(Link, VARIABLE_ID, Link, VARIABLE_SIGNATURE);
  250. if( Var->Flags == VOL ) {
  251. Print(L" * %h-.*s : %s\n", SLen, Var->Name, Var->u.Str);
  252. }
  253. else {
  254. Print(L" %h-.*s : %s\n", SLen, Var->Name, Var->u.Str);
  255. }
  256. if (PageBreaks) {
  257. ScreenCount++;
  258. if (ScreenCount > ScreenSize - 4) {
  259. ScreenCount = 0;
  260. Print (L"\nPress Return to contiue :");
  261. Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
  262. Print (L"\n\n");
  263. }
  264. }
  265. }
  266. } else {
  267. /*
  268. * Find the specified value
  269. */
  270. for (Link=Head->Flink; Link != Head; Link=Link->Flink) {
  271. Var = CR(Link, VARIABLE_ID, Link, VARIABLE_SIGNATURE);
  272. if (StriCmp(Var->Name, Name) == 0) {
  273. Found = Var;
  274. break;
  275. }
  276. }
  277. if (Found && Delete) {
  278. /*
  279. * Remove it from the store
  280. */
  281. Status = RT->SetVariable (Found->Name, Guid, 0, 0, NULL);
  282. if (Status == EFI_NOT_FOUND) {
  283. Print (L"Set/Alias: could not find '%hs'\n", Found->Name);
  284. Status = EFI_SUCCESS;
  285. }
  286. } else if (Value) {
  287. /*
  288. * Add it to the store
  289. */
  290. if( Found && ( ( Volatile && ( Found->Flags == NON_VOL ) ) ||
  291. ( !Volatile && ( Found->Flags == VOL ) ) ) )
  292. {
  293. if( Found->Flags == NON_VOL ) {
  294. Print (L"Set/Alias: '%hs' already exists as non-volatile variable\n", Found->Name ) ;
  295. }
  296. else {
  297. Print (L"Set/Alias: '%hs' already exists as volatile variable\n", Found->Name ) ;
  298. }
  299. Found = NULL ;
  300. Status = EFI_ACCESS_DENIED ;
  301. }
  302. else
  303. {
  304. Status = RT->SetVariable (
  305. Found ? Found->Name : Name,
  306. Guid,
  307. EFI_VARIABLE_BOOTSERVICE_ACCESS | ( Volatile ? 0 : EFI_VARIABLE_NON_VOLATILE ),
  308. StrSize(Value),
  309. Value
  310. );
  311. if (!EFI_ERROR(Status)) {
  312. /*
  313. * Make a new in memory copy
  314. */
  315. Size = sizeof(VARIABLE_ID) + StrSize(Name) + StrSize(Value);
  316. Var = AllocateZeroPool (Size);
  317. Var->Signature = VARIABLE_SIGNATURE;
  318. Var->u.Value = ((UINT8 *) Var) + sizeof(VARIABLE_ID);
  319. Var->Name = (CHAR16*) (Var->u.Value + StrSize(Value));
  320. Var->ValueSize = StrSize(Value);
  321. StrCpy (Var->u.Str, Value);
  322. StrCpy (Var->Name, Found ? Found->Name : Name);
  323. if( Volatile ) {
  324. Var->Flags = VOL ;
  325. }
  326. else {
  327. Var->Flags = NON_VOL ;
  328. }
  329. InsertTailList (Head, &Var->Link);
  330. }
  331. }
  332. } else {
  333. if (Found) {
  334. Print(L" %hs : %s\n", Var->Name, Var->u.Str);
  335. } else {
  336. Print(L"'%es' not found\n", Name);
  337. }
  338. Found = NULL;
  339. }
  340. /*
  341. * Remove the old in memory copy if there was one
  342. */
  343. if (Found) {
  344. RemoveEntryList (&Found->Link);
  345. FreePool (Found);
  346. }
  347. }
  348. ReleaseLock (&SEnvLock);
  349. return Status;
  350. }
  351. EFI_STATUS
  352. SEnvCmdSet (
  353. IN EFI_HANDLE ImageHandle,
  354. IN EFI_SYSTEM_TABLE *SystemTable
  355. )
  356. /* Code for internal shell "set" command */
  357. {
  358. return SEnvCmdSA (ImageHandle, SystemTable, &SEnvEnv, &SEnvEnvId);
  359. }
  360. EFI_STATUS
  361. SEnvCmdAlias (
  362. IN EFI_HANDLE ImageHandle,
  363. IN EFI_SYSTEM_TABLE *SystemTable
  364. )
  365. /* Code for internal shell "set" command */
  366. {
  367. return SEnvCmdSA (ImageHandle, SystemTable, &SEnvAlias, &SEnvAliasId);
  368. }