Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

almisc.c

Go to the documentation of this file.
00001 #include "precomp.h" 00002 #pragma hdrstop 00003 00004 00005 // 00006 // Internal function definitions 00007 // 00008 00009 ARC_STATUS 00010 AlpFreeComponents( 00011 IN PCHAR *EnvVarComponents 00012 ); 00013 00014 BOOLEAN 00015 AlpMatchComponent( 00016 IN PCHAR Value1, 00017 IN PCHAR Value2 00018 ); 00019 00020 // 00021 // Function implementations 00022 // 00023 00024 00025 ARC_STATUS 00026 AlGetEnvVarComponents ( 00027 IN PCHAR EnvValue, 00028 OUT PCHAR **EnvVarComponents, 00029 OUT PULONG PNumComponents 00030 ) 00031 00032 /*++ 00033 00034 Routine Description: 00035 00036 This routine takes an environment variable string and turns it into 00037 the constituent value strings: 00038 00039 Example EnvValue = "Value1;Value2;Value3" is turned into: 00040 00041 "Value1", "Value2", "Value3" 00042 00043 The following are valid value strings: 00044 00045 1. " " :one null value is found 00046 2. ";;;; " :five null values are found 00047 3. " ;Value1 ; Value2;Value3;;;;;;; ;" :12 value strings are found, 00048 :9 of which are null 00049 00050 If an invalid component (contains embedded white space) is found in the 00051 string then this routine attempts to resynch to the next value, no error 00052 is returned, and a the first part of the invalid value is returned for the 00053 bad component. 00054 00055 1. " Value1;Bad Value2; Value3" : 2 value strings are found 00056 00057 The value strings returned suppress all whitespace before and after the 00058 value. 00059 00060 00061 Arguments: 00062 00063 EnvValue: ptr to zero terminated environment value string 00064 00065 EnvVarComponents: ptr to a PCHAR * variable to receive the buffer of 00066 ptrs to the constituent value strings. 00067 00068 PNumComponents: ptr to a ULONG to receive the number of value strings found 00069 00070 Return Value: 00071 00072 The function returns the following error codes: 00073 EACCES if EnvValue is NULL 00074 ENOMEM if the memory allocation fails 00075 00076 00077 The function returns the following success codes: 00078 ESUCCESS. 00079 00080 When the function returns ESUCCESS: 00081 - *PNumComponent field gets the number of value strings found 00082 - if the number is non zero the *EnvVarComponents field gets the 00083 ptr to the buffer containing ptrs to value strings 00084 00085 --*/ 00086 00087 00088 { 00089 PCHAR pchStart, pchEnd, pchNext; 00090 PCHAR pchComponents[MAX_COMPONENTS + 1]; 00091 ULONG NumComponents, i; 00092 PCHAR pch; 00093 ULONG size; 00094 00095 // 00096 // Validate the EnvValue 00097 // 00098 if (EnvValue == NULL) { 00099 return (EACCES); 00100 } 00101 00102 // 00103 // Initialise the ptr array with nulls 00104 // 00105 for (i = 0; i < (MAX_COMPONENTS+1); i++) { 00106 pchComponents[i] = NULL; 00107 } 00108 00109 // 00110 // Initialise ptrs to search components 00111 // 00112 pchStart = EnvValue; 00113 NumComponents = 0; 00114 00115 00116 // 00117 // search till either pchStart reaches the end or till max components 00118 // is reached, the below has been programmed from a dfsa. 00119 // 00120 while (*pchStart && NumComponents < MAX_COMPONENTS) { 00121 00122 // 00123 // STATE 1: find the beginning of next variable value 00124 // 00125 while (*pchStart!=0 && isspace(*pchStart)) { 00126 pchStart++; 00127 } 00128 00129 00130 if (*pchStart == 0) { 00131 break; 00132 } 00133 00134 // 00135 // STATE 2: In the midst of a value 00136 // 00137 pchEnd = pchStart; 00138 while (*pchEnd!=0 && !isspace(*pchEnd) && *pchEnd!=';') { 00139 pchEnd++; 00140 } 00141 00142 // 00143 // STATE 3: spit out the value found 00144 // 00145 00146 size = pchEnd - pchStart; 00147 if ((pch = AlAllocateHeap(size+1)) == NULL) { 00148 AlpFreeComponents(pchComponents); 00149 return (ENOMEM); 00150 } 00151 strncpy (pch, pchStart, size); 00152 pch[size]=0; 00153 pchComponents[NumComponents++]=pch; 00154 00155 // 00156 // STATE 4: variable value end has been reached, find the beginning 00157 // of the next value 00158 // 00159 if ((pchNext = strchr(pchEnd, ';')) == NULL) { 00160 break; // out of the big while loop because we are done 00161 } 00162 00163 // 00164 // Advance beyond the semicolon. 00165 // 00166 00167 pchNext++; 00168 00169 // 00170 // reinitialise to begin STATE 1 00171 // 00172 pchStart = pchNext; 00173 00174 } // end while. 00175 00176 // 00177 // Get memory to hold an environment pointer and return that 00178 // 00179 00180 if ( NumComponents!=0 ) { 00181 PCHAR *pch; 00182 00183 if ((pch = (PCHAR *)AlAllocateHeap((NumComponents+1)*sizeof(PCHAR))) == NULL) { 00184 AlpFreeComponents(pchComponents); 00185 return (ENOMEM); 00186 } 00187 00188 // 00189 // the last one is NULL because we initialised the array with NULLs 00190 // 00191 00192 for ( i = 0; i <= NumComponents; i++) { 00193 pch[i] = pchComponents[i]; 00194 } 00195 00196 00197 *EnvVarComponents = pch; 00198 } 00199 00200 // 00201 // Update the number of elements field and return success 00202 // 00203 *PNumComponents = NumComponents; 00204 return (ESUCCESS); 00205 } 00206 00207 00208 ARC_STATUS 00209 AlFreeEnvVarComponents ( 00210 IN PCHAR *EnvVarComponents 00211 ) 00212 /*++ 00213 00214 Routine Description: 00215 00216 This routine frees up all the components in the ptr array and frees 00217 up the storage for the ptr array itself too 00218 00219 Arguments: 00220 00221 EnvVarComponents: the ptr to the PCHAR * Buffer 00222 00223 Return Value: 00224 00225 ESUCCESS if freeing successful 00226 EACCES if memory ptr invalid 00227 00228 00229 00230 --*/ 00231 00232 00233 { 00234 ARC_STATUS Status; 00235 00236 // 00237 // if the pointer is NULL just return success 00238 // 00239 if (EnvVarComponents == NULL) { 00240 return (ESUCCESS); 00241 } 00242 00243 // 00244 // free all the components first, if error in freeing return 00245 // 00246 Status = AlpFreeComponents(EnvVarComponents); 00247 if (Status != ESUCCESS) { 00248 return Status; 00249 } 00250 00251 // 00252 // free the component holder too 00253 // 00254 if( AlDeallocateHeap(EnvVarComponents) != NULL) { 00255 return (EACCES); 00256 } 00257 else { 00258 return (ESUCCESS); 00259 } 00260 00261 } 00262 00263 00264 ARC_STATUS 00265 AlpFreeComponents( 00266 IN PCHAR *EnvVarComponents 00267 ) 00268 00269 /*++ 00270 00271 Routine Description: 00272 00273 This routine frees up only the components in the ptr array, but doesn't 00274 free the ptr array storage itself. 00275 00276 Arguments: 00277 00278 EnvVarComponents: the ptr to the PCHAR * Buffer 00279 00280 Return Value: 00281 00282 ESUCCESS if freeing successful 00283 EACCES if memory ptr invalid 00284 00285 --*/ 00286 00287 { 00288 00289 // 00290 // get all the components and free them 00291 // 00292 while (*EnvVarComponents != NULL) { 00293 if(AlDeallocateHeap(*EnvVarComponents++) != NULL) { 00294 return(EACCES); 00295 } 00296 } 00297 00298 return(ESUCCESS); 00299 } 00300 00301 00302 BOOLEAN 00303 AlpMatchComponent( 00304 IN PCHAR Value1, 00305 IN PCHAR Value2 00306 ) 00307 00308 /*++ 00309 00310 Routine Description: 00311 00312 This routine compares two components to see if they are equal. This is 00313 essentially comparing strings except that leading zeros are stripped from 00314 key values. 00315 00316 Arguments: 00317 00318 Value1 - Supplies a pointer to the first value to match. 00319 00320 Value2 - Supplies a pointer to the second value to match. 00321 00322 00323 Return Value: 00324 00325 If the components match, TRUE is returned, otherwise FALSE is returned. 00326 00327 --*/ 00328 00329 { 00330 while ((*Value1 != 0) && (*Value2 != 0)) { 00331 if (tolower(*Value1) != tolower(*Value2)) { 00332 return FALSE; 00333 } 00334 00335 if (*Value1 == '(') { 00336 do { 00337 *Value1++; 00338 } while (*Value1 == '0'); 00339 } else { 00340 *Value1++; 00341 } 00342 00343 if (*Value2 == '(') { 00344 do { 00345 *Value2++; 00346 } while (*Value2 == '0'); 00347 } else { 00348 *Value2++; 00349 } 00350 } 00351 00352 if ((*Value1 == 0) && (*Value2 == 0)) { 00353 return TRUE; 00354 } 00355 00356 return FALSE; 00357 } 00358 00359 00360 BOOLEAN 00361 AlFindNextMatchComponent( 00362 IN PCHAR EnvValue, 00363 IN PCHAR MatchValue, 00364 IN ULONG StartComponent, 00365 OUT PULONG MatchComponent OPTIONAL 00366 ) 00367 00368 /*++ 00369 00370 Routine Description: 00371 00372 This routine compares each component of EnvValue, starting with 00373 StartComponent, until a match is found or there are no more components. 00374 00375 Arguments: 00376 00377 EnvValue - Supplies a pointer to the environment variable value. 00378 00379 MatchValue - Supplies a pointer to the value to match. 00380 00381 StartComponent - Supplies the component number to start the match. 00382 00383 MatchComponent - Supplies an optional pointer to a variable to receive 00384 the number of the component that matched. 00385 00386 Return Value: 00387 00388 If a match is found, TRUE is returned, otherwise FALSE is returned. 00389 00390 --*/ 00391 00392 { 00393 ARC_STATUS Status; 00394 PCHAR *EnvVarComponents; 00395 ULONG NumComponents; 00396 ULONG Index; 00397 BOOLEAN Match; 00398 00399 00400 Status = AlGetEnvVarComponents(EnvValue, &EnvVarComponents, &NumComponents); 00401 00402 if (Status != ESUCCESS) { 00403 return FALSE; 00404 } 00405 00406 Match = FALSE; 00407 for (Index = StartComponent ; Index < NumComponents ; Index++ ) { 00408 if (AlpMatchComponent(EnvVarComponents[Index], MatchValue)) { 00409 Match = TRUE; 00410 break; 00411 } 00412 } 00413 00414 if (ARGUMENT_PRESENT(MatchComponent)) { 00415 *MatchComponent = Index; 00416 } 00417 00418 AlFreeEnvVarComponents(EnvVarComponents); 00419 return Match; 00420 } 00421 00422 00423 ARC_STATUS 00424 AlAddSystemPartition( 00425 IN PCHAR NewSystemPartition 00426 ) 00427 00428 /*++ 00429 00430 Routine Description: 00431 00432 This routine adds a system partition to the SystemPartition environment 00433 variable, and updates the Osloader, OsloadPartition, OsloadFilename, 00434 and OsloadOptions variables. 00435 00436 Arguments: 00437 00438 SystemPartition - Supplies a pointer to the pathname of the system 00439 partition to add. 00440 00441 Return Value: 00442 00443 If the system partition was successfully added, ESUCCESS is returned, 00444 otherwise an error code is returned. 00445 00446 BUGBUG - This program is simplistic and doesn't attempt to make sure all 00447 the variables are consistent. It also doesn't fail gracefully. 00448 00449 --*/ 00450 00451 { 00452 ARC_STATUS Status; 00453 PCHAR SystemPartition; 00454 CHAR TempValue[MAXIMUM_ENVIRONMENT_VALUE]; 00455 //PCHAR Osloader; 00456 //PCHAR OsloadPartition; 00457 //PCHAR OsloadFilename; 00458 //PCHAR OsloadOptions; 00459 00460 // 00461 // Get the system partition environment variable. 00462 // 00463 00464 SystemPartition = ArcGetEnvironmentVariable("SystemPartition"); 00465 00466 // 00467 // If the variable doesn't exist, add it and exit. 00468 // 00469 00470 if (SystemPartition == NULL) { 00471 if(strlen(NewSystemPartition) < MAXIMUM_ENVIRONMENT_VALUE) { 00472 Status = ArcSetEnvironmentVariable("SystemPartition", 00473 NewSystemPartition); 00474 } else { 00475 Status = E2BIG; 00476 } 00477 return Status; 00478 } 00479 00480 // 00481 // If the variable exists, add the new partition to the end. 00482 // 00483 if(strlen(SystemPartition)+strlen(NewSystemPartition)+2 > MAXIMUM_ENVIRONMENT_VALUE) { 00484 return(E2BIG); 00485 } 00486 00487 strcpy(TempValue, SystemPartition); 00488 strcat(TempValue, ";"); 00489 strcat(TempValue, NewSystemPartition); 00490 Status = ArcSetEnvironmentVariable("SystemPartition", 00491 TempValue); 00492 00493 if (Status != ESUCCESS) { 00494 return Status; 00495 } 00496 00497 #if 0 00498 // 00499 // Add semicolons to the end of each of the associated variables. 00500 // If they don't exist add them. 00501 // 00502 00503 // 00504 // Get the Osloader environment variable and add a semicolon to the end. 00505 // 00506 00507 Osloader = ArcGetEnvironmentVariable("Osloader"); 00508 if (Osloader == NULL) { 00509 *TempValue = 0; 00510 } else { 00511 strcpy(TempValue, Osloader); 00512 } 00513 strcat(TempValue, ";"); 00514 Status = ArcSetEnvironmentVariable("Osloader",TempValue); 00515 00516 if (Status != ESUCCESS) { 00517 return Status; 00518 } 00519 00520 // 00521 // Get the OsloadPartition environment variable and add a semicolon to the end. 00522 // 00523 00524 OsloadPartition = ArcGetEnvironmentVariable("OsloadPartition"); 00525 if (OsloadPartition == NULL) { 00526 *TempValue = 0; 00527 } else { 00528 strcpy(TempValue, OsloadPartition); 00529 } 00530 strcat(TempValue, ";"); 00531 Status = ArcSetEnvironmentVariable("OsloadPartition",TempValue); 00532 00533 if (Status != ESUCCESS) { 00534 return Status; 00535 } 00536 00537 // 00538 // Get the OsloadFilename environment variable and add a semicolon to the end. 00539 // 00540 00541 OsloadFilename = ArcGetEnvironmentVariable("OsloadFilename"); 00542 if (OsloadFilename == NULL) { 00543 *TempValue = 0; 00544 } else { 00545 strcpy(TempValue, OsloadFilename); 00546 } 00547 strcat(TempValue, ";"); 00548 Status = ArcSetEnvironmentVariable("OsloadFilename",TempValue); 00549 00550 if (Status != ESUCCESS) { 00551 return Status; 00552 } 00553 00554 // 00555 // Get the OsloadOptions environment variable and add a semicolon to the end. 00556 // 00557 00558 OsloadOptions = ArcGetEnvironmentVariable("OsloadOptions"); 00559 if (OsloadOptions == NULL) { 00560 *TempValue = 0; 00561 } else { 00562 strcpy(TempValue, OsloadOptions); 00563 } 00564 strcat(TempValue, ";"); 00565 Status = ArcSetEnvironmentVariable("OsloadOptions",TempValue); 00566 #endif 00567 return Status; 00568 } 00569 00570 00571 typedef struct _tagMENUITEM { 00572 PCHAR Text; 00573 ULONG AssociatedData; 00574 } MENUITEM,*PMENUITEM; 00575 00576 typedef struct _tagMENUCOOKIE { 00577 ULONG ItemCount; 00578 PMENUITEM Items; 00579 } MENUCOOKIE,*PMENUCOOKIE; 00580 00581 00582 // indent for menus, status, etc. 00583 00584 char MARGIN[] = " "; 00585 char MSGMARGIN[] = " "; 00586 00587 // special constants used when fetching keystrokes 00588 00589 #define KEY_UP 1 00590 #define KEY_DOWN 2 00591 00592 00593 VOID 00594 MarkLine( 00595 ULONG Line, 00596 BOOLEAN Selected, 00597 PCHAR String 00598 ); 00599 00600 BOOLEAN 00601 CommonMenuDisplay( 00602 PMENUCOOKIE Menu, 00603 BOOLEAN StaticMenu, 00604 PCHAR Items[], 00605 ULONG ItemCount, 00606 BOOLEAN PrintOnly, 00607 ULONG AssociatedDataOfDefaultChoice, 00608 ULONG *AssociatedDataOfChoice, 00609 PCHAR MenuName, 00610 ULONG Row 00611 ); 00612 00613 char 00614 GetChar( 00615 VOID 00616 ); 00617 00618 00619 BOOLEAN 00620 AlInitializeMenuPackage( 00621 VOID 00622 ) 00623 { 00624 return(TRUE); 00625 } 00626 00627 00628 ULONG 00629 AlGetMenuNumberItems( 00630 PVOID MenuID 00631 ) 00632 { 00633 return(((PMENUCOOKIE)MenuID)->ItemCount); 00634 } 00635 00636 00637 ULONG 00638 AlGetMenuAssociatedData( 00639 PVOID MenuID, 00640 ULONG n 00641 ) 00642 { 00643 return(((PMENUCOOKIE)MenuID)->Items[n].AssociatedData); 00644 } 00645 00646 BOOLEAN 00647 AlNewMenu( 00648 PVOID *MenuID 00649 ) 00650 { 00651 PMENUCOOKIE p; 00652 00653 if(!(p = AlAllocateHeap(sizeof(MENUCOOKIE)))) { 00654 return(FALSE); 00655 } 00656 p->ItemCount = 0; 00657 p->Items = NULL; 00658 *MenuID = p; 00659 return(TRUE); 00660 } 00661 00662 00663 VOID 00664 AlFreeMenu( 00665 PVOID MenuID 00666 ) 00667 { 00668 PMENUCOOKIE p = MenuID; 00669 ULONG i; 00670 00671 for(i=0; i<p->ItemCount; i++) { 00672 if(p->Items[i].Text != NULL) { 00673 AlDeallocateHeap(p->Items[i].Text); 00674 } 00675 } 00676 if(p->Items) { 00677 AlDeallocateHeap(p->Items); 00678 } 00679 AlDeallocateHeap(p); 00680 } 00681 00682 00683 BOOLEAN 00684 AlAddMenuItem( 00685 PVOID MenuID, 00686 PCHAR Text, 00687 ULONG AssociatedData, 00688 ULONG Attributes // unused 00689 ) 00690 { 00691 PMENUCOOKIE Menu = MenuID; 00692 PMENUITEM p; 00693 00694 DBG_UNREFERENCED_PARAMETER(Attributes); 00695 00696 if(!Menu->ItemCount) { 00697 if((Menu->Items = AlAllocateHeap(sizeof(MENUITEM))) == NULL) { 00698 return(FALSE); 00699 } 00700 Menu->ItemCount = 1; 00701 p = Menu->Items; 00702 } else { 00703 if((p = AlReallocateHeap(Menu->Items,sizeof(MENUITEM)*(Menu->ItemCount+1))) == NULL) { 00704 return(FALSE); 00705 } 00706 Menu->Items = p; 00707 p = &Menu->Items[Menu->ItemCount++]; 00708 } 00709 00710 if((p->Text = AlAllocateHeap(strlen(Text)+1)) == NULL) { 00711 return(FALSE); 00712 } 00713 strcpy(p->Text,Text); 00714 p->AssociatedData = AssociatedData; 00715 return(TRUE); 00716 } 00717 00718 00719 BOOLEAN 00720 AlAddMenuItems( 00721 PVOID MenuID, 00722 PCHAR Text[], 00723 ULONG ItemCount 00724 ) 00725 { 00726 ULONG base,i; 00727 00728 base = AlGetMenuNumberItems(MenuID); 00729 00730 for(i=0; i<ItemCount; i++) { 00731 if(!AlAddMenuItem(MenuID,Text[i],i+base,0)) { 00732 return(FALSE); 00733 } 00734 } 00735 return(TRUE); 00736 } 00737 00738 00739 BOOLEAN 00740 AlDisplayMenu( 00741 PVOID MenuID, 00742 BOOLEAN PrintOnly, 00743 ULONG AssociatedDataOfDefaultChoice, 00744 ULONG *AssociatedDataOfChoice, 00745 ULONG Row, 00746 PCHAR MenuName 00747 ) 00748 { 00749 return(CommonMenuDisplay((PMENUCOOKIE)MenuID, 00750 FALSE, 00751 NULL, 00752 ((PMENUCOOKIE)MenuID)->ItemCount, 00753 PrintOnly, 00754 AssociatedDataOfDefaultChoice, 00755 AssociatedDataOfChoice, 00756 MenuName, 00757 Row 00758 ) 00759 ); 00760 } 00761 00762 00763 BOOLEAN 00764 AlDisplayStaticMenu( 00765 PCHAR Items[], 00766 ULONG ItemCount, 00767 ULONG DefaultChoice, 00768 ULONG Row, 00769 ULONG *IndexOfChoice 00770 ) 00771 { 00772 return(CommonMenuDisplay(NULL, 00773 TRUE, 00774 Items, 00775 ItemCount, 00776 FALSE, 00777 DefaultChoice, 00778 IndexOfChoice, 00779 NULL, 00780 Row 00781 ) 00782 ); 00783 } 00784 00785 00786 00787 BOOLEAN 00788 CommonMenuDisplay( 00789 PMENUCOOKIE Menu, 00790 BOOLEAN StaticMenu, 00791 PCHAR Items[], 00792 ULONG ItemCount, 00793 BOOLEAN PrintOnly, 00794 ULONG AssociatedDataOfDefaultChoice, 00795 ULONG *AssociatedDataOfChoice, 00796 PCHAR MenuName, 00797 ULONG Row 00798 ) 00799 { 00800 // ULONG x; 00801 ULONG i,MenuBaseLine,Selection; 00802 char c; 00803 PCHAR String; 00804 00805 AlSetPosition(Row,0); 00806 AlPrint("%cJ",ASCI_CSI); // clear to end of screen. 00807 MenuBaseLine = Row; 00808 00809 AlSetScreenColor(7,4); // white on blue 00810 00811 // if(MenuName) { 00812 // AlPrint("%s%s\r\n%s",MARGIN,MenuName,MARGIN); 00813 // x = strlen(MenuName); 00814 // for(i=0; i<x; i++) { 00815 // AlPrint("-"); 00816 // } 00817 // AlPrint("\r\n\r\n"); 00818 // MenuBaseLine += 3; 00819 // } 00820 00821 for(i=0; i<ItemCount; i++) { 00822 AlSetScreenAttributes(1,0,0); // hi intensity 00823 AlPrint("%s%s\r\n",MARGIN,StaticMenu ? Items[i] : Menu->Items[i].Text); 00824 } 00825 00826 if(PrintOnly) { 00827 00828 char dummy; 00829 AlPrint("\r\nPress any key to continue."); 00830 AlGetString(&dummy,0); 00831 00832 } else { 00833 00834 // AlPrint("\r\n%sMake Selection using arrow keys and return,\r\n%sor escape to cancel",MARGIN,MARGIN); 00835 00836 Selection = 0; 00837 if(StaticMenu) { 00838 Selection = AssociatedDataOfDefaultChoice; 00839 } else { 00840 for(i=0; i<ItemCount; i++) { 00841 if(Menu->Items[i].AssociatedData == AssociatedDataOfDefaultChoice) { 00842 Selection = i; 00843 break; 00844 } 00845 } 00846 } 00847 00848 String = StaticMenu ? Items[Selection] : Menu->Items[Selection].Text; 00849 MarkLine(MenuBaseLine+Selection,TRUE, String); 00850 00851 while(((c = GetChar()) != ASCI_ESC) && (c != ASCI_LF) && (c != ASCI_CR)) { 00852 00853 String = StaticMenu ? Items[Selection] : Menu->Items[Selection].Text; 00854 MarkLine(MenuBaseLine+Selection,FALSE,String); 00855 00856 if(c == KEY_UP) { 00857 if(!Selection--) { 00858 Selection = ItemCount - 1; 00859 } 00860 } else if(c == KEY_DOWN) { 00861 if(++Selection == ItemCount) { 00862 Selection = 0; 00863 } 00864 } 00865 00866 String = StaticMenu ? Items[Selection] : Menu->Items[Selection].Text; 00867 MarkLine(MenuBaseLine+Selection,TRUE,String); 00868 } 00869 00870 // set cursor to a free place on the screen. 00871 AlSetPosition(MenuBaseLine + ItemCount + 4,0); 00872 00873 if(c == ASCI_ESC) { 00874 return(FALSE); 00875 } 00876 00877 *AssociatedDataOfChoice = StaticMenu ? Selection : Menu->Items[Selection].AssociatedData; 00878 } 00879 return(TRUE); 00880 } 00881 00882 00883 00884 VOID 00885 MarkLine( 00886 ULONG Line, 00887 BOOLEAN Selected, 00888 PCHAR String 00889 ) 00890 { 00891 AlSetPosition(Line,sizeof(MARGIN)); 00892 if (Selected) { 00893 AlSetScreenAttributes(1,0,1); // hi intensity, Reverse Video 00894 } 00895 AlPrint("%s\r\n", String); 00896 AlSetScreenAttributes(1,0,0); // hi intensity 00897 } 00898 00899 00900 00901 char 00902 GetChar( 00903 VOID 00904 ) 00905 { 00906 UCHAR c; 00907 ULONG count; 00908 00909 ArcRead(ARC_CONSOLE_INPUT,&c,1,&count); 00910 switch(c) { 00911 // case ASCI_ESC: 00912 // ArcRead(ARC_CONSOLE_INPUT,&c,1,&count); 00913 // if(c != '[') { 00914 // break; 00915 // } 00916 case ASCI_CSI: 00917 ArcRead(ARC_CONSOLE_INPUT,&c,1,&count); 00918 switch(c) { 00919 case 'A': 00920 case 'D': 00921 return(KEY_UP); 00922 case 'B': 00923 case 'C': 00924 return(KEY_DOWN); 00925 } 00926 default: 00927 return(c); 00928 } 00929 } 00930 00931 00932 00933 VOID 00934 AlWaitKey( 00935 PCHAR Prompt 00936 ) 00937 { 00938 char buff[1]; 00939 00940 AlPrint(MSGMARGIN); 00941 AlPrint(Prompt ? Prompt : "Press any key to continue..."); 00942 AlGetString(buff,0); 00943 } 00944 00945 00946 VOID 00947 vAlStatusMsg( 00948 IN ULONG Row, 00949 IN BOOLEAN Error, 00950 IN PCHAR FormatString, 00951 IN va_list ArgumentList 00952 ) 00953 { 00954 char text[256]; 00955 ULONG Length,Count; 00956 00957 AlSetPosition(Row,0); 00958 AlPrint(MSGMARGIN); 00959 Length = vsprintf(text,FormatString,ArgumentList); 00960 if(Error) { 00961 AlSetScreenColor(1,4); // red on blue 00962 } else { 00963 AlSetScreenColor(3,4); // yellow on blue 00964 } 00965 AlSetScreenAttributes(1,0,0); // hi intensity 00966 ArcWrite(ARC_CONSOLE_OUTPUT,text,Length,&Count); 00967 AlPrint("\r\n"); 00968 AlSetScreenColor(7,4); // white on blue 00969 AlSetScreenAttributes(1,0,0); // hi intensity 00970 } 00971 00972 00973 VOID 00974 AlStatusMsg( 00975 IN ULONG TopRow, 00976 IN ULONG BottomRow, 00977 IN BOOLEAN Error, 00978 IN PCHAR FormatString, 00979 ... 00980 ) 00981 { 00982 va_list ArgList; 00983 00984 va_start(ArgList,FormatString); 00985 vAlStatusMsg(TopRow,Error,FormatString,ArgList); 00986 00987 AlWaitKey(NULL); 00988 AlClearStatusArea(TopRow,BottomRow); 00989 } 00990 00991 00992 VOID 00993 AlStatusMsgNoWait( 00994 IN ULONG TopRow, 00995 IN ULONG BottomRow, 00996 IN BOOLEAN Error, 00997 IN PCHAR FormatString, 00998 ... 00999 ) 01000 { 01001 va_list ArgList; 01002 01003 AlClearStatusArea(TopRow,BottomRow); 01004 va_start(ArgList,FormatString); 01005 vAlStatusMsg(TopRow,Error,FormatString,ArgList); 01006 } 01007 01008 01009 VOID 01010 AlClearStatusArea( 01011 IN ULONG TopRow, 01012 IN ULONG BottomRow 01013 ) 01014 { 01015 ULONG i; 01016 01017 for(i=BottomRow; i>=TopRow; --i) { 01018 AlSetPosition(i,0); 01019 AlClearLine(); 01020 } 01021 } 01022 01023 01024 ARC_STATUS 01025 AlGetMenuSelection( 01026 01027 IN PCHAR szTitle, 01028 IN PCHAR *rgszSelections, 01029 IN ULONG crgsz, 01030 IN ULONG crow, 01031 IN ULONG irgszDefault, 01032 OUT PULONG pirgsz, 01033 OUT PCHAR *pszSelection 01034 ) 01035 /*++ 01036 01037 Routine Description: 01038 01039 This routine takes an array of strings, turns them into a menu 01040 and gets a selection. If ESC hit then ESUCCESS is returned with 01041 the *pszSelection NULL. 01042 01043 crgsz is assume to be 1 or greater. 01044 01045 01046 Arguments: 01047 01048 szTitle - Pointer to menu title to pass to AlDisplayMenu 01049 prgszSelection - pointer to an array of strings for menu 01050 crgsz - count of strings 01051 irgszDefault - index in rgszSelection to use as default selection 01052 01053 Return Value: 01054 01055 irgsz - index to selection 01056 pszSelection - pointer int rgszSelection for selection. Note that 01057 this is not a dup and should not be freed seperately 01058 then rgszSelections. 01059 01060 Note: if ARC_STATUS == ESUCCESS and pszSelection == NULL then the 01061 menu was successfully displayed but the user hit ESC to select 01062 nothing from the menu. 01063 01064 --*/ 01065 01066 01067 { 01068 01069 PVOID hdMenuId; 01070 01071 *pszSelection = NULL; 01072 if (!AlNewMenu(&hdMenuId)) { 01073 01074 return( ENOMEM ); 01075 01076 } 01077 01078 // 01079 // BUGBUG for now 1 selection will also build a menu, in the 01080 // future once this is working we should just return that selection 01081 // 01082 01083 if (!AlAddMenuItems(hdMenuId, rgszSelections, crgsz)) { 01084 01085 AlFreeMenu(hdMenuId); 01086 return( ENOMEM ); 01087 01088 } 01089 01090 if (!AlDisplayMenu(hdMenuId, 01091 FALSE, 01092 irgszDefault, 01093 pirgsz, 01094 crow, 01095 szTitle)) { 01096 01097 // 01098 // User did not pick a system partition. return NULL 01099 // can caller should abort 01100 // 01101 AlFreeMenu(hdMenuId); 01102 return( ESUCCESS ); 01103 01104 } 01105 01106 AlFreeMenu(hdMenuId); 01107 *pszSelection = rgszSelections[*pirgsz]; 01108 return( ESUCCESS ); 01109 01110 } 01111 01112 PCHAR 01113 AlStrDup( 01114 01115 IN PCHAR szString 01116 ) 01117 01118 /*++ 01119 01120 Routine Description: 01121 01122 This routine makes a copy of the passed in string. I do not use 01123 the CRT strdup since it uses malloc. 01124 01125 Arguments: 01126 01127 szString - pointer of string to dup. 01128 01129 Return Value: 01130 01131 pointer to dup'd string. NULL if could not allocate 01132 01133 --*/ 01134 { 01135 01136 PCHAR szT; 01137 01138 if (szT = AlAllocateHeap(strlen(szString) + 1)) { 01139 01140 strcpy(szT, szString); 01141 return(szT); 01142 01143 } 01144 return( NULL ); 01145 01146 } 01147 01148 01149 PCHAR 01150 AlCombinePaths ( 01151 01152 IN PCHAR szPath1, 01153 IN PCHAR szPath2 01154 ) 01155 01156 /*++ 01157 01158 Routine Description: 01159 01160 This routine combines to strings. It allocate a new string 01161 to hold both strings. 01162 01163 Arguments: 01164 01165 pointer to combined path. NULL if failed to allocate. 01166 01167 Return Value: 01168 01169 01170 --*/ 01171 { 01172 01173 PCHAR szT; 01174 01175 if (szT = AlAllocateHeap(strlen(szPath1) + strlen(szPath2) + 1)) { 01176 01177 strcpy(szT, szPath1); 01178 strcat(szT, szPath2); 01179 return( szT ); 01180 01181 } else { 01182 01183 return ( NULL ); 01184 01185 } 01186 01187 } 01188 01189 VOID 01190 AlFreeArray ( 01191 01192 IN BOOLEAN fFreeArray, 01193 IN PCHAR *rgsz, 01194 IN ULONG csz 01195 ) 01196 /*++ 01197 01198 Routine Description: 01199 01200 This routine iterates through an array of pointers to strings freeing 01201 each string and finally the array itself. 01202 01203 Arguments: 01204 01205 fFreeArray - flag wither to free the array itself. 01206 rgsz - pointer to array of strings. 01207 csz - size of array. 01208 01209 Return Value: 01210 01211 01212 --*/ 01213 01214 { 01215 01216 ULONG irgsz; 01217 01218 if (!csz) { 01219 01220 return; 01221 01222 } 01223 01224 for( irgsz = 0; irgsz < csz; irgsz++ ) { 01225 01226 if (rgsz[irgsz]) { 01227 01228 AlDeallocateHeap(rgsz[irgsz]); 01229 01230 } else { 01231 01232 break; 01233 01234 } 01235 01236 } 01237 if (fFreeArray) { 01238 AlDeallocateHeap( rgsz ); 01239 } 01240 01241 } 01242 01243 ARC_STATUS 01244 AlGetBase ( 01245 IN PCHAR szPath, 01246 OUT PCHAR *pszBase 01247 ) 01248 01249 /*++ 01250 01251 Routine Description: 01252 01253 01254 This routine strips the filename off a path. 01255 01256 Arguments: 01257 01258 szPath - path to strip. 01259 01260 Return Value: 01261 01262 pszBaseh - pointer to buffer holding new base. (this is a copy) 01263 01264 --*/ 01265 01266 { 01267 01268 PCHAR szPathT; 01269 01270 // 01271 // Make local copy of szArcInstPath so we can alter it 01272 // 01273 *pszBase = AlStrDup(szPath); 01274 if ( *pszBase == NULL ) { 01275 01276 return( ENOMEM ); 01277 } 01278 01279 // 01280 // The start of the path part should be either a \ or a ) where 01281 // ) is the end of the arc name 01282 // 01283 if ((szPathT = strrchr(*pszBase,'\\')) == 0) { 01284 if ((szPathT = strrchr(*pszBase, ')')) == 0) { 01285 01286 AlDeallocateHeap(*pszBase); 01287 return( EBADSYNTAX ); 01288 } 01289 } 01290 01291 01292 // 01293 // Cut filename out 01294 // 01295 // szPath points to either ')' or '\' so need to move over that 01296 // onto actual name 01297 // 01298 *(szPathT + 1) = 0; 01299 return( ESUCCESS ); 01300 01301 01302 } 01303 01304 // 01305 // Define static data. 01306 // 01307 01308 01309 PCHAR AdapterTypes[AdapterMaximum + 1] = {"eisa","scsi", "multi", NULL}; 01310 01311 PCHAR ControllerTypes[ControllerMaximum + 1] = {"cdrom", "disk", NULL}; 01312 01313 PCHAR PeripheralTypes[PeripheralMaximum + 1] = {"rdisk", "fdisk", NULL}; 01314 01315 01316 01317 PCHAR 01318 AlGetNextArcNamToken ( 01319 IN PCHAR TokenString, 01320 OUT PCHAR OutputToken, 01321 OUT PULONG UnitNumber 01322 ) 01323 01324 /*++ 01325 01326 Routine Description: 01327 01328 This routine scans the specified token string for the next token and 01329 unit number. The token format is: 01330 01331 name[(unit)] 01332 01333 Arguments: 01334 01335 TokenString - Supplies a pointer to a zero terminated token string. 01336 01337 OutputToken - Supplies a pointer to a variable that receives the next 01338 token. 01339 01340 UnitNumber - Supplies a pointer to a variable that receives the unit 01341 number. 01342 01343 Return Value: 01344 01345 If another token exists in the token string, then a pointer to the 01346 start of the next token is returned. Otherwise, a value of NULL is 01347 returned. 01348 01349 --*/ 01350 01351 { 01352 01353 // 01354 // If there are more characters in the token string, then parse the 01355 // next token. Otherwise, return a value of NULL. 01356 // 01357 01358 if (*TokenString == '\0') { 01359 return NULL; 01360 01361 } else { 01362 while ((*TokenString != '\0') && (*TokenString != '(')) { 01363 *OutputToken++ = *TokenString++; 01364 } 01365 01366 *OutputToken = '\0'; 01367 01368 // 01369 // If a unit number is specified, then convert it to binary. 01370 // Otherwise, default the unit number to zero. 01371 // 01372 01373 *UnitNumber = 0; 01374 if (*TokenString == '(') { 01375 TokenString += 1; 01376 while ((*TokenString != '\0') && (*TokenString != ')')) { 01377 *UnitNumber = (*UnitNumber * 10) + (*TokenString++ - '0'); 01378 } 01379 01380 if (*TokenString == ')') { 01381 TokenString += 1; 01382 } 01383 } 01384 } 01385 01386 return TokenString; 01387 } 01388 01389 01390 ULONG 01391 AlMatchArcNamToken ( 01392 IN PCHAR TokenValue, 01393 IN TOKEN_TYPE TokenType 01394 ) 01395 01396 /*++ 01397 01398 Routine Description: 01399 01400 This routine attempts to match a token with an array of possible 01401 values. 01402 01403 Arguments: 01404 01405 TokenValue - Supplies a pointer to a zero terminated token value. 01406 01407 TokenType - Indicates which type of token we are dealing with 01408 (AdapterType/ControllerType/PeripheralType) 01409 01410 Return Value: 01411 01412 If the token type is invalid, INVALID_TOKEN_TYPE is returned. 01413 01414 If a token match is not located, then a value INVALID_TOKEN_VALUE 01415 is returned. 01416 01417 If a token match is located, then the ENUM value of the token is 01418 returned. 01419 01420 --*/ 01421 01422 { 01423 01424 ULONG Index; 01425 PCHAR MatchString; 01426 PCHAR TokenString; 01427 PCHAR *TokenArray; 01428 BOOLEAN Found; 01429 01430 // 01431 // Depending on token type choose the appropriate token string array 01432 // 01433 switch (TokenType) { 01434 case AdapterType: 01435 TokenArray = AdapterTypes; 01436 break; 01437 01438 case ControllerType: 01439 TokenArray = ControllerTypes; 01440 break; 01441 01442 case PeripheralType: 01443 TokenArray = PeripheralTypes; 01444 break; 01445 01446 default: 01447 return ((ULONG)INVALID_TOKEN_TYPE); 01448 } 01449 01450 // 01451 // Scan the match array until either a match is found or all of 01452 // the match strings have been scanned. 01453 // 01454 // BUGBUG** The code below can be easily implemented using _strcmpi. 01455 // 01456 01457 Index = 0; 01458 Found = FALSE; 01459 while (TokenArray[Index] != NULL) { 01460 MatchString = TokenArray[Index]; 01461 TokenString = TokenValue; 01462 while ((*MatchString != '\0') && (*TokenString != '\0')) { 01463 if (toupper(*MatchString) != toupper(*TokenString)) { 01464 break; 01465 } 01466 01467 MatchString += 1; 01468 TokenString += 1; 01469 } 01470 01471 if ((*MatchString == '\0') && (*TokenString == '\0')) { 01472 Found = TRUE; 01473 break; 01474 } 01475 01476 Index += 1; 01477 } 01478 01479 return (Found ? Index : INVALID_TOKEN_VALUE); 01480 } 01481 01482 ULONG 01483 AlPrint ( 01484 PCHAR Format, 01485 ... 01486 ) 01487 01488 { 01489 01490 va_list arglist; 01491 UCHAR Buffer[256]; 01492 ULONG Count; 01493 ULONG Length; 01494 01495 // 01496 // Format the output into a buffer and then print it. 01497 // 01498 01499 va_start(arglist, Format); 01500 Length = vsprintf(Buffer, Format, arglist); 01501 ArcWrite( ARC_CONSOLE_OUTPUT, Buffer, Length, &Count); 01502 va_end(arglist); 01503 return 0; 01504 } 01505 01506 01507 BOOLEAN 01508 AlGetString( 01509 OUT PCHAR String, 01510 IN ULONG StringLength 01511 ) 01512 01513 /*++ 01514 01515 Routine Description: 01516 01517 This routine reads a string from standardin until a 01518 carriage return or escape is found or StringLength is reached. 01519 01520 Arguments: 01521 01522 String - Supplies a pointer to where the string will be stored. 01523 01524 StringLength - Supplies the Max Length to read. 01525 01526 Return Value: 01527 01528 FALSE if user pressed esc, TRUE otherwise. 01529 01530 --*/ 01531 01532 { 01533 CHAR c; 01534 ULONG Count; 01535 PCHAR Buffer; 01536 01537 Buffer = String; 01538 while (ArcRead(ARC_CONSOLE_INPUT,&c,1,&Count)==ESUCCESS) { 01539 if(c == ASCI_ESC) { 01540 return(FALSE); 01541 } 01542 if ((c=='\r') || (c=='\n') || ((ULONG)(Buffer-String) == StringLength)) { 01543 *Buffer='\0'; 01544 ArcWrite(ARC_CONSOLE_OUTPUT,"\r\n",2,&Count); 01545 return(TRUE); 01546 } 01547 // 01548 // Check for backspace; 01549 // 01550 if (c=='\b') { 01551 if (((ULONG)Buffer > (ULONG)String)) { 01552 Buffer--; 01553 ArcWrite(ARC_CONSOLE_OUTPUT,"\b \b",3,&Count); 01554 } 01555 } else { 01556 // 01557 // If it's a printable char store it and display it. 01558 // 01559 if (isprint(c)) { 01560 *Buffer++ = c; 01561 ArcWrite(ARC_CONSOLE_OUTPUT,&c,1,&Count); 01562 } 01563 } 01564 } 01565 }

Generated on Sat May 15 19:39:15 2004 for test by doxygen 1.3.7