VOID SlFlushConsoleBuffer( VOID ) /*++ Routine Description: This routine flushes the console buffer, so that we don't have any pre-existing keypresses in the buffer when we prompt the user to 'press any key to continue.' Arguments: NONE Return Value: NONE --*/ { UCHAR c; ULONG count; while(ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) { ArcRead(ARC_CONSOLE_INPUT, &c, 1, &count); } }
const DEVVTBL* IsoMount(ULONG DeviceId) { UCHAR Buffer[SECTORSIZE]; PPVD Pvd = (PPVD)Buffer; LARGE_INTEGER Position; ULONG Count; LONG ret; // // Read The Primary Volume Descriptor // Position.HighPart = 0; Position.LowPart = 16 * SECTORSIZE; ret = ArcSeek(DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) return NULL; ret = ArcRead(DeviceId, Pvd, SECTORSIZE, &Count); if (ret != ESUCCESS || Count < sizeof(PVD)) return NULL; // // Check if PVD is valid. If yes, return ISO9660 function table // if (Pvd->VdType == 1 && RtlEqualMemory(Pvd->StandardId, "CD001", 5)) return &Iso9660FuncTable; else return NULL; }
PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size, TYPE_OF_MEMORY MemoryType) { ULONG FileId; PVOID PhysicalBase; FILEINFORMATION FileInfo; ULONG FileSize; ULONG Status; ULONG BytesRead; //CHAR ProgressString[256]; /* Inform user we are loading files */ //sprintf(ProgressString, "Loading %s...", FileName); //UiDrawProgressBarCenter(1, 100, ProgressString); TRACE("Loading module %s\n", ModuleName); *Size = 0; /* Open the image file */ Status = ArcOpen((PCHAR)ModuleName, OpenReadOnly, &FileId); if (Status != ESUCCESS) { /* In case of errors, we just return, without complaining to the user */ return NULL; } /* Get this file's size */ Status = ArcGetFileInformation(FileId, &FileInfo); if (Status != ESUCCESS) { ArcClose(FileId); return NULL; } FileSize = FileInfo.EndingAddress.LowPart; *Size = FileSize; /* Allocate memory */ PhysicalBase = MmAllocateMemoryWithType(FileSize, MemoryType); if (PhysicalBase == NULL) { ArcClose(FileId); return NULL; } /* Load whole file */ Status = ArcRead(FileId, PhysicalBase, FileSize, &BytesRead); ArcClose(FileId); if (Status != ESUCCESS) { return NULL; } TRACE("Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize); return PhysicalBase; }
char prom_getchar(void) { ULONG cnt; CHAR c; bc_disable(); ArcRead(0, &c, 1, &cnt); bc_enable(); return c; }
/* Generic SGI handler for (spurious) 8254 interrupts */ void indy_8254timer_irq(void) { int irq = SGI_8254_0_IRQ; ULONG cnt; char c; irq_enter(); kstat_this_cpu.irqs[irq]++; printk(KERN_ALERT "Oops, got 8254 interrupt.\n"); ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); irq_exit(); }
/* Generic SGI handler for (spurious) 8254 interrupts */ void __irq_entry indy_8254timer_irq(void) { int irq = SGI_8254_0_IRQ; ULONG cnt; char c; irq_enter(); kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); printk(KERN_ALERT "Oops, got 8254 interrupt.\n"); ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); irq_exit(); }
static int __init string_to_cpu(char *s) { long cnt; char c; int i; for(i = 0; i < NUM_CPUS; i++) { if(!strcmp(s, sgi_cputable[i].name)) return sgi_cputable[i].type; } prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s); prom_printf("press a key to reboot\n"); ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); return 0; }
/* * IsoBufferDirectory() * This function allocates a buffer, reads the specified directory * and returns a pointer to that buffer into pDirectoryBuffer. The * function returns an ARC error code. The directory is specified * by its starting sector and length. */ static LONG IsoBufferDirectory(ULONG DeviceId, ULONG DirectoryStartSector, ULONG DirectoryLength, PVOID* pDirectoryBuffer) { PVOID DirectoryBuffer; ULONG SectorCount; LARGE_INTEGER Position; ULONG Count; ULONG ret; TRACE("IsoBufferDirectory() DirectoryStartSector = %d DirectoryLength = %d\n", DirectoryStartSector, DirectoryLength); SectorCount = ROUND_UP(DirectoryLength, SECTORSIZE) / SECTORSIZE; TRACE("Trying to read (DirectoryCount) %d sectors.\n", SectorCount); // // Attempt to allocate memory for directory buffer // TRACE("Trying to allocate (DirectoryLength) %d bytes.\n", DirectoryLength); DirectoryBuffer = MmHeapAlloc(DirectoryLength); if (!DirectoryBuffer) return ENOMEM; // // Now read directory contents into DirectoryBuffer // Position.HighPart = 0; Position.LowPart = DirectoryStartSector * SECTORSIZE; ret = ArcSeek(DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) { MmHeapFree(DirectoryBuffer); return ret; } ret = ArcRead(DeviceId, DirectoryBuffer, SectorCount * SECTORSIZE, &Count); if (ret != ESUCCESS || Count != SectorCount * SECTORSIZE) { MmHeapFree(DirectoryBuffer); return EIO; } *pDirectoryBuffer = DirectoryBuffer; return ESUCCESS; }
BOOLEAN HackGetYesNo ( VOID ) /*++ Routine Description: This asks the user to type a Y or N for a debug clause located later in this module. This is only needed while I am trying to understand the FlashFile ROM update failures, and should be removed when the problem is resolved. Arguments: None. Return Value: TRUE if the user hits the Y key. FALSE otherwise. --*/ { CHAR Character; ULONG Count; VenPrint(FWUP_YORN_MSG); while (ArcGetReadStatus(ARC_CONSOLE_INPUT) != ESUCCESS) { } ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count); VenPrint1("%c\r\n", Character); if ((Character == FWUP_LOWER_Y) || (Character == FWUP_UPPER_Y)) { return TRUE; } else { return FALSE; } }
BOOLEAN JnFsProceedWithUpdate ( VOID ) /*++ Routine Description: This function asks the user if she wants to proceed. Arguments: None. Return Value: Returns TRUE if the user typed a Y on the keyboard. FALSE if some other key is typed. --*/ { CHAR Character; ULONG Count; ARC_STATUS Status = EAGAIN; VenPrint(FWUP_PRESS_Y_TO_CONTINUE_MSG); while (Status != ESUCCESS) { Status = ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count); } if ((Character == FWUP_LOWER_Y) || (Character == FWUP_UPPER_Y)) { return TRUE; } else { VenPrint(FWUP_UPDATE_ABORTED_MSG); return FALSE; } }
VOID FwWaitForKeypress( IN BOOLEAN ShowTheTime ) /*++ Routine Description: This routine waits for a keypress, then returns. Arguments: ShowTheTime TRUE = display the time. FALSE = do not display the time. Return Value: None. --*/ { UCHAR Character; ULONG Count; VenPrint(SS_PRESS_KEY_MSG); while (ArcGetReadStatus(ARC_CONSOLE_INPUT) != ESUCCESS) { #if !defined(JNUPDATE) && !defined(FAILSAFE_BOOTER) if (ShowTheTime) { JzShowTime(FALSE); } #endif } ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count); VenPrint1("%c2J", ASCII_CSI); }
NTSTATUS NTAPI IopReadBootRecord( IN PDEVICE_OBJECT DeviceObject, IN ULONGLONG LogicalSectorNumber, IN ULONG SectorSize, OUT PMASTER_BOOT_RECORD BootRecord) { ULONG FileId = (ULONG)DeviceObject; LARGE_INTEGER Position; ULONG BytesRead; ARC_STATUS Status; Position.QuadPart = LogicalSectorNumber * SectorSize; Status = ArcSeek(FileId, &Position, SeekAbsolute); if (Status != ESUCCESS) return STATUS_IO_DEVICE_ERROR; Status = ArcRead(FileId, BootRecord, SectorSize, &BytesRead); if (Status != ESUCCESS || BytesRead != SectorSize) return STATUS_IO_DEVICE_ERROR; return STATUS_SUCCESS; }
void __init prom_init(void) { PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK; romvec = ROMVECTOR; prom_argc = fw_arg0; _prom_argv = (LONG *) fw_arg1; _prom_envp = (LONG *) fw_arg2; if (pb->magic != 0x53435241) { printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n", (unsigned long) pb->magic); while(1) ; } prom_init_cmdline(); prom_identify_arch(); printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n", pb->ver, pb->rev); prom_meminit(); #ifdef DEBUG_PROM_INIT pr_info("Press a key to reboot\n"); ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); #endif #ifdef CONFIG_SGI_IP27 { extern struct plat_smp_ops ip27_smp_ops; register_smp_ops(&ip27_smp_ops); } #endif }
ULONG JzDisplayMenu ( IN PCHAR Choices[], IN ULONG NumberOfChoices, IN LONG DefaultChoice, IN ULONG CurrentLine, IN LONG AutobootValue, IN BOOLEAN ShowTheTime ) /*++ Routine Description: Displays a menu and gets a selection. This routine assumes that the entries in the Choices array do not have two adjacent blank rows, and that the first and last rows are not blank. Arguments: Choices[] The menu choices array NumberOfChoices The 1-based number of entries in Choices[] DefaultChoice The 0-based entry which should be highlighted as the default choice. CurrentLine The current line on the video. AutobootValue If zero, do not do an autoboot countdown. If nonzero, do an autoboot countdown with this value. ShowTheTime If true, the time is displayed in the upper right hand corner. Return Value: Returns -1 if the escape key is pressed, otherwise returns the menu item selected, where 0 is the first item. --*/ { ULONG Index; UCHAR Character; ULONG Count; ULONG PreviousTime; ULONG RelativeTime; BOOLEAN Timeout; #ifndef JNUPDATE // // Setup for autoboot // if (AutobootValue == 0) { Timeout = FALSE; AutobootValue = 1; } else { Timeout = TRUE; PreviousTime = FwGetRelativeTime(); } #else Timeout = FALSE; AutobootValue = 1; #endif // // Display the menu // for (Index = 0; Index < NumberOfChoices ; Index++ ) { VenSetPosition( Index + CurrentLine, 5); if (Index == DefaultChoice) { VenSetScreenAttributes( TRUE, FALSE, TRUE); VenPrint(Choices[Index]); VenSetScreenAttributes( TRUE, FALSE, FALSE); } else { VenPrint(Choices[Index]); } } Character = 0; do { #ifndef JNUPDATE if (ShowTheTime) { JzShowTime(FALSE); } #endif if (ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) { ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count); switch (Character) { case ASCII_ESC: VenStallExecution(10000); if (ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) { ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count); if (Character != '[') { return(-1); } } else { return(-1); } // We purposely fall through to ASCII_CSI. case ASCII_CSI: ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count); VenSetPosition( DefaultChoice + CurrentLine, 5); VenPrint(Choices[DefaultChoice]); switch (Character) { case 'A': case 'D': DefaultChoice--; if (DefaultChoice < 0) { DefaultChoice = NumberOfChoices - 1; } if (*Choices[DefaultChoice] == 0) { DefaultChoice--; } break; case 'B': case 'C': DefaultChoice++; if (DefaultChoice == NumberOfChoices) { DefaultChoice = 0; } if (*Choices[DefaultChoice] == 0) { DefaultChoice++; } break; case 'H': DefaultChoice = 0; break; default: break; } VenSetPosition( DefaultChoice + CurrentLine, 5); VenSetScreenAttributes( TRUE, FALSE, TRUE); VenPrint(Choices[DefaultChoice]); VenSetScreenAttributes( TRUE, FALSE, FALSE); continue; default: break; } } // // If default choice is nonzero and a timeout is active, remove // the timeout. // if ((DefaultChoice != 0) && Timeout) { Timeout = FALSE; VenSetPosition(NumberOfChoices + 9, 0); VenPrint("\x9bK"); } #ifndef JNUPDATE // // Update the timeout value if active. // if (Timeout) { RelativeTime = FwGetRelativeTime(); if (RelativeTime != PreviousTime) { PreviousTime = RelativeTime; VenSetPosition(NumberOfChoices + 9, 62); VenPrint("\x9bK"); VenPrint1("%d", AutobootValue--); } } #endif } while ((Character != '\n') && (Character != ASCII_CR) && (AutobootValue >= 0)); return DefaultChoice; }
LONG IsoRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) { PISO_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); UCHAR SectorBuffer[SECTORSIZE]; LARGE_INTEGER Position; ULONG DeviceId; ULONG FilePointer; ULONG SectorNumber; ULONG OffsetInSector; ULONG LengthInSector; ULONG NumberOfSectors; ULONG BytesRead; LONG ret; TRACE("IsoRead() Buffer = %p, N = %lu\n", Buffer, N); DeviceId = FsGetDeviceId(FileId); *Count = 0; // // If they are trying to read past the // end of the file then return success // with Count == 0 // FilePointer = FileHandle->FilePointer; if (FilePointer >= FileHandle->FileSize) { return ESUCCESS; } // // If they are trying to read more than there is to read // then adjust the amount to read // if (FilePointer + N > FileHandle->FileSize) { N = FileHandle->FileSize - FilePointer; } // // Ok, now we have to perform at most 3 calculations // I'll draw you a picture (using nifty ASCII art): // // CurrentFilePointer -+ // | // +----------------+ // | // +-----------+-----------+-----------+-----------+ // | Sector 1 | Sector 2 | Sector 3 | Sector 4 | // +-----------+-----------+-----------+-----------+ // | | // +---------------+--------------------+ // | // N -----------------+ // // 1 - The first calculation (and read) will align // the file pointer with the next sector // boundary (if we are supposed to read that much) // 2 - The next calculation (and read) will read // in all the full sectors that the requested // amount of data would cover (in this case // sectors 2 & 3). // 3 - The last calculation (and read) would read // in the remainder of the data requested out of // the last sector. // // // Only do the first read if we // aren't aligned on a cluster boundary // if (FilePointer % SECTORSIZE) { // // Do the math for our first read // SectorNumber = FileHandle->FileStart + (FilePointer / SECTORSIZE); OffsetInSector = FilePointer % SECTORSIZE; LengthInSector = (N > (SECTORSIZE - OffsetInSector)) ? (SECTORSIZE - OffsetInSector) : N; // // Now do the read and update Count, N, FilePointer, & Buffer // Position.HighPart = 0; Position.LowPart = SectorNumber * SECTORSIZE; ret = ArcSeek(DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) { return ret; } ret = ArcRead(DeviceId, SectorBuffer, SECTORSIZE, &BytesRead); if (ret != ESUCCESS || BytesRead != SECTORSIZE) { return EIO; } RtlCopyMemory(Buffer, SectorBuffer + OffsetInSector, LengthInSector); *Count += LengthInSector; N -= LengthInSector; FilePointer += LengthInSector; Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInSector); } // // Do the math for our second read (if any data left) // if (N > 0) { // // Determine how many full clusters we need to read // NumberOfSectors = (N / SECTORSIZE); SectorNumber = FileHandle->FileStart + (FilePointer / SECTORSIZE); // // Now do the read and update Count, N, FilePointer, & Buffer // Position.HighPart = 0; Position.LowPart = SectorNumber * SECTORSIZE; ret = ArcSeek(DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) { return ret; } ret = ArcRead(DeviceId, Buffer, NumberOfSectors * SECTORSIZE, &BytesRead); if (ret != ESUCCESS || BytesRead != NumberOfSectors * SECTORSIZE) { return EIO; } *Count += NumberOfSectors * SECTORSIZE; N -= NumberOfSectors * SECTORSIZE; FilePointer += NumberOfSectors * SECTORSIZE; Buffer = (PVOID)((ULONG_PTR)Buffer + NumberOfSectors * SECTORSIZE); } // // Do the math for our third read (if any data left) // if (N > 0) { SectorNumber = FileHandle->FileStart + (FilePointer / SECTORSIZE); // // Now do the read and update Count, N, FilePointer, & Buffer // Position.HighPart = 0; Position.LowPart = SectorNumber * SECTORSIZE; ret = ArcSeek(DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) { return ret; } ret = ArcRead(DeviceId, SectorBuffer, SECTORSIZE, &BytesRead); if (ret != ESUCCESS || BytesRead != SECTORSIZE) { return EIO; } RtlCopyMemory(Buffer, SectorBuffer, N); *Count += N; FilePointer += N; } TRACE("IsoRead() done\n"); return ESUCCESS; }
/* * IsoLookupFile() * This function searches the file system for the * specified filename and fills in an ISO_FILE_INFO structure * with info describing the file, etc. returns ARC error code */ static LONG IsoLookupFile(PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO IsoFileInfoPointer) { UCHAR Buffer[SECTORSIZE]; PPVD Pvd = (PPVD)Buffer; UINT32 i; ULONG NumberOfPathParts; CHAR PathPart[261]; PVOID DirectoryBuffer; ULONG DirectorySector; ULONG DirectoryLength; ISO_FILE_INFO IsoFileInfo; LARGE_INTEGER Position; ULONG Count; LONG ret; TRACE("IsoLookupFile() FileName = %s\n", FileName); RtlZeroMemory(IsoFileInfoPointer, sizeof(ISO_FILE_INFO)); RtlZeroMemory(&IsoFileInfo, sizeof(ISO_FILE_INFO)); // // Read The Primary Volume Descriptor // Position.HighPart = 0; Position.LowPart = 16 * SECTORSIZE; ret = ArcSeek(DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) return ret; ret = ArcRead(DeviceId, Pvd, SECTORSIZE, &Count); if (ret != ESUCCESS || Count < sizeof(PVD)) return EIO; DirectorySector = Pvd->RootDirRecord.ExtentLocationL; DirectoryLength = Pvd->RootDirRecord.DataLengthL; // // Figure out how many sub-directories we are nested in // NumberOfPathParts = FsGetNumPathParts(FileName); // // Loop once for each part // for (i=0; i<NumberOfPathParts; i++) { // // Get first path part // FsGetFirstNameFromPath(PathPart, FileName); // // Advance to the next part of the path // for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++) { } FileName++; // // Buffer the directory contents // ret = IsoBufferDirectory(DeviceId, DirectorySector, DirectoryLength, &DirectoryBuffer); if (ret != ESUCCESS) return ret; // // Search for file name in directory // if (!IsoSearchDirectoryBufferForFile(DirectoryBuffer, DirectoryLength, PathPart, &IsoFileInfo)) { MmHeapFree(DirectoryBuffer); return ENOENT; } MmHeapFree(DirectoryBuffer); // // If we have another sub-directory to go then // grab the start sector and file size // if ((i+1) < NumberOfPathParts) { DirectorySector = IsoFileInfo.FileStart; DirectoryLength = IsoFileInfo.FileSize; } } RtlCopyMemory(IsoFileInfoPointer, &IsoFileInfo, sizeof(ISO_FILE_INFO)); return ESUCCESS; }
BOOLEAN WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath, IN LPCSTR HiveName) { ULONG FileId; CHAR FullHiveName[256]; LONG Status; FILEINFORMATION FileInfo; ULONG HiveFileSize; ULONG_PTR HiveDataPhysical; PVOID HiveDataVirtual; ULONG BytesRead; LPCWSTR FsService; /* Concatenate path and filename to get the full name */ strcpy(FullHiveName, DirectoryPath); strcat(FullHiveName, HiveName); //Print(L"Loading %s...\n", FullHiveName); Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId); if (Status != ESUCCESS) { UiMessageBox("Opening hive file failed!"); return FALSE; } /* Get the file length */ Status = ArcGetFileInformation(FileId, &FileInfo); if (Status != ESUCCESS) { ArcClose(FileId); UiMessageBox("Hive file has 0 size!"); return FALSE; } HiveFileSize = FileInfo.EndingAddress.LowPart; /* Round up the size to page boundary and alloc memory */ HiveDataPhysical = (ULONG_PTR)MmAllocateMemoryWithType( MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT, LoaderRegistryData); if (HiveDataPhysical == 0) { ArcClose(FileId); UiMessageBox("Unable to alloc memory for a hive!"); return FALSE; } /* Convert address to virtual */ HiveDataVirtual = PaToVa((PVOID)HiveDataPhysical); /* Fill LoaderBlock's entries */ LoaderBlock->RegistryLength = HiveFileSize; LoaderBlock->RegistryBase = HiveDataVirtual; /* Finally read from file to the memory */ Status = ArcRead(FileId, (PVOID)HiveDataPhysical, HiveFileSize, &BytesRead); if (Status != ESUCCESS) { ArcClose(FileId); UiMessageBox("Unable to read from hive file!"); return FALSE; } // Add boot filesystem driver to the list FsService = FsGetServiceName(FileId); if (FsService) { TRACE(" Adding filesystem service %S\n", FsService); Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", NULL, (LPWSTR)FsService); if (!Status) TRACE(" Failed to add filesystem service\n"); } else { TRACE(" No required filesystem service\n"); } ArcClose(FileId); return TRUE; }
BOOLEAN WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath, IN LPCSTR AnsiFileName, IN LPCSTR OemFileName, IN LPCSTR LanguageFileName) { CHAR FileName[255]; ULONG AnsiFileId; ULONG OemFileId; ULONG LanguageFileId; ULONG AnsiFileSize, OemFileSize, LanguageFileSize; ULONG TotalSize; ULONG_PTR NlsDataBase; PVOID NlsVirtual; BOOLEAN AnsiEqualsOem = FALSE; FILEINFORMATION FileInfo; ULONG BytesRead, Status; /* There may be a case, when OEM and ANSI page coincide */ if (!strcmp(AnsiFileName, OemFileName)) AnsiEqualsOem = TRUE; /* Open file with ANSI and store its size */ //Print(L"Loading %s...\n", Filename); strcpy(FileName, DirectoryPath); strcat(FileName, AnsiFileName); Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId); if (Status != ESUCCESS) goto Failure; Status = ArcGetFileInformation(AnsiFileId, &FileInfo); if (Status != ESUCCESS) goto Failure; AnsiFileSize = FileInfo.EndingAddress.LowPart; TRACE("AnsiFileSize: %d\n", AnsiFileSize); ArcClose(AnsiFileId); /* Open OEM file and store its length */ if (AnsiEqualsOem) { OemFileSize = 0; } else { //Print(L"Loading %s...\n", Filename); strcpy(FileName, DirectoryPath); strcat(FileName, OemFileName); Status = ArcOpen(FileName, OpenReadOnly, &OemFileId); if (Status != ESUCCESS) goto Failure; Status = ArcGetFileInformation(OemFileId, &FileInfo); if (Status != ESUCCESS) goto Failure; OemFileSize = FileInfo.EndingAddress.LowPart; ArcClose(OemFileId); } TRACE("OemFileSize: %d\n", OemFileSize); /* And finally open the language codepage file and store its length */ //Print(L"Loading %s...\n", Filename); strcpy(FileName, DirectoryPath); strcat(FileName, LanguageFileName); Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId); if (Status != ESUCCESS) goto Failure; Status = ArcGetFileInformation(LanguageFileId, &FileInfo); if (Status != ESUCCESS) goto Failure; LanguageFileSize = FileInfo.EndingAddress.LowPart; ArcClose(LanguageFileId); TRACE("LanguageFileSize: %d\n", LanguageFileSize); /* Sum up all three length, having in mind that every one of them must start at a page boundary => thus round up each file to a page */ TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + MM_SIZE_TO_PAGES(OemFileSize) + MM_SIZE_TO_PAGES(LanguageFileSize); /* Store it for later marking the pages as NlsData type */ TotalNLSSize = TotalSize; NlsDataBase = (ULONG_PTR)MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData); if (NlsDataBase == 0) goto Failure; NlsVirtual = PaToVa((PVOID)NlsDataBase); LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); /* Ansi and OEM data are the same - just set pointers to the same area */ if (AnsiEqualsOem) LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; /* Now actually read the data into memory, starting with Ansi file */ strcpy(FileName, DirectoryPath); strcat(FileName, AnsiFileName); Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId); if (Status != ESUCCESS) goto Failure; Status = ArcRead(AnsiFileId, VaToPa(LoaderBlock->NlsData->AnsiCodePageData), AnsiFileSize, &BytesRead); if (Status != ESUCCESS) goto Failure; ArcClose(AnsiFileId); /* OEM now, if it doesn't equal Ansi of course */ if (!AnsiEqualsOem) { strcpy(FileName, DirectoryPath); strcat(FileName, OemFileName); Status = ArcOpen(FileName, OpenReadOnly, &OemFileId); if (Status != ESUCCESS) goto Failure; Status = ArcRead(OemFileId, VaToPa(LoaderBlock->NlsData->OemCodePageData), OemFileSize, &BytesRead); if (Status != ESUCCESS) goto Failure; ArcClose(OemFileId); } /* finally the language file */ strcpy(FileName, DirectoryPath); strcat(FileName, LanguageFileName); Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId); if (Status != ESUCCESS) goto Failure; Status = ArcRead(LanguageFileId, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData), LanguageFileSize, &BytesRead); if (Status != ESUCCESS) goto Failure; ArcClose(LanguageFileId); // // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK // Should go to WinLdrLoadOemHalFont(), when it will be implemented // LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); /* Convert NlsTables address to VA */ LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); return TRUE; Failure: //UiMessageBox("Error reading NLS file %s\n", Filename); UiMessageBox("Error reading NLS file!"); return FALSE; }
BOOLEAN BlReadSignature( IN PCHAR DiskName, IN BOOLEAN IsCdRom ) /*++ Routine Description: Given an ARC disk name, reads the MBR and adds its signature to the list of disks. Arguments: Diskname - Supplies the name of the disk. IsCdRom - Indicates whether the disk is a CD-ROM. Return Value: TRUE - Success FALSE - Failure --*/ { PARC_DISK_SIGNATURE Signature; UCHAR SectorBuffer[2048+256]; UCHAR Partition[100]; ULONG DiskId; ULONG Status; LARGE_INTEGER SeekValue; PUCHAR Sector; ULONG i; ULONG Sum; ULONG Count; ULONG SectorSize; if (IsCdRom) { SectorSize = 2048; } else { SectorSize = 512; } Signature = BlAllocateHeap(sizeof(ARC_DISK_SIGNATURE)); if (Signature==NULL) { return(FALSE); } Signature->ArcName = BlAllocateHeap(strlen(DiskName)+2); if (Signature->ArcName==NULL) { return(FALSE); } #if defined(_i386_) // // NTDETECT creates an "eisa(0)..." arcname for detected // BIOS disks on an EISA machine. Change this to "multi(0)..." // in order to be consistent with the rest of the system // (particularly the arcname in boot.ini) // if (_strnicmp(DiskName,"eisa",4)==0) { strcpy(Signature->ArcName,"multi"); strcpy(Partition,"multi"); strcat(Signature->ArcName,DiskName+4); strcat(Partition,DiskName+4); } else { strcpy(Signature->ArcName, DiskName); strcpy(Partition, DiskName); } #else strcpy(Signature->ArcName, DiskName); strcpy(Partition, DiskName); #endif strcat(Partition, "partition(0)"); Status = ArcOpen(Partition, ArcOpenReadOnly, &DiskId); if (Status != ESUCCESS) { return(TRUE); } // // Read in the first sector // Sector = ALIGN_BUFFER(SectorBuffer); if (IsCdRom) { // // For a CD-ROM, the interesting data starts at 0x8000. // SeekValue.QuadPart = 0x8000; } else { SeekValue.QuadPart = 0; } Status = ArcSeek(DiskId, &SeekValue, SeekAbsolute); if (Status == ESUCCESS) { Status = ArcRead(DiskId, Sector, SectorSize, &Count); } ArcClose(DiskId); if (Status != ESUCCESS) { return(TRUE); } // // Check to see whether this disk has a valid partition table signature or not. // if (((PUSHORT)Sector)[BOOT_SIGNATURE_OFFSET] != BOOT_RECORD_SIGNATURE) { Signature->ValidPartitionTable = FALSE; } else { Signature->ValidPartitionTable = TRUE; } Signature->Signature = ((PULONG)Sector)[PARTITION_TABLE_OFFSET/2-1]; // // compute the checksum // Sum = 0; for (i=0; i<(SectorSize/4); i++) { Sum += ((PULONG)Sector)[i]; } Signature->CheckSum = ~Sum + 1; InsertHeadList(&BlLoaderBlock->ArcDiskInformation->DiskSignatures, &Signature->ListEntry); return(TRUE); }
/* * We' call this early before loadmmu(). If we do the other way around * the firmware will crash and burn. */ void __init sgi_sysinit(void) { pcomponent *p, *toplev, *cpup = 0; int cputype = -1; long cnt; char c; /* The root component tells us what machine architecture we * have here. */ p = ArcGetChild(PROM_NULL_COMPONENT); /* Now scan for cpu(s). */ toplev = p = ArcGetChild(p); while(p) { int ncpus = 0; if(p->type == Cpu) { if(++ncpus > 1) { prom_printf("\nYeee, SGI MP not ready yet\n"); prom_printf("press a key to reboot\n"); ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); } printk("CPU: %s ", p->iname); cpup = p; cputype = string_to_cpu(cpup->iname); } p = ArcGetPeer(p); } if (cputype == -1) { prom_printf("\nYeee, could not find cpu ARCS component\n"); prom_printf("press a key to reboot\n"); ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); } p = ArcGetChild(cpup); while(p) { switch(p->class) { case processor: switch(p->type) { case Fpu: printk("FPU<%s> ", p->iname); break; default: break; }; break; case cache: switch(p->type) { case picache: printk("ICACHE "); break; case pdcache: printk("DCACHE "); break; case sccache: printk("SCACHE "); break; default: break; }; break; default: break; }; p = ArcGetPeer(p); } printk("\n"); }
BOOLEAN IniFileInitialize(VOID) { FILEINFORMATION FileInformation; ULONG FileId; // File handle for freeldr.ini PCHAR FreeLoaderIniFileData; ULONG FreeLoaderIniFileSize, Count; LONG ret; BOOLEAN Success; TRACE("IniFileInitialize()\n"); // // Open freeldr.ini // ret = IniOpenIniFile(&FileId); if (ret != ESUCCESS) { UiMessageBoxCritical("Error opening freeldr.ini or file not found.\nYou need to re-install FreeLoader."); return FALSE; } // // Get the file size // ret = ArcGetFileInformation(FileId, &FileInformation); if (ret != ESUCCESS || FileInformation.EndingAddress.HighPart != 0) { UiMessageBoxCritical("Error while getting informations about freeldr.ini.\nYou need to re-install FreeLoader."); return FALSE; } FreeLoaderIniFileSize = FileInformation.EndingAddress.LowPart; // // Allocate memory to cache the whole freeldr.ini // FreeLoaderIniFileData = MmHeapAlloc(FreeLoaderIniFileSize); if (!FreeLoaderIniFileData) { UiMessageBoxCritical("Out of memory while loading freeldr.ini."); ArcClose(FileId); return FALSE; } // // Read freeldr.ini off the disk // ret = ArcRead(FileId, FreeLoaderIniFileData, FreeLoaderIniFileSize, &Count); if (ret != ESUCCESS || Count != FreeLoaderIniFileSize) { UiMessageBoxCritical("Error while reading freeldr.ini."); ArcClose(FileId); MmHeapFree(FreeLoaderIniFileData); return FALSE; } // // Parse the .ini file data // Success = IniParseFile(FreeLoaderIniFileData, FreeLoaderIniFileSize); // // Do some cleanup, and return // ArcClose(FileId); MmHeapFree(FreeLoaderIniFileData); return Success; }
ARC_STATUS LowReadSectors( IN ULONG VolumeId, IN ULONG SectorSize, IN ULONG StartingSector, IN ULONG NumberOfSectors, OUT PVOID Buffer ) /*++ Routine Description: This routine reads 'NumberOfSectors' sectors starting at sector 'StartingSector' on the volume with ID 'VolumeId'. Arguments: VolumeId - Supplies the ID for the volume. SectorSize - Supplies the number of bytes per sector. StartingSector - Supplies the starting sector for the read. NumberOfSectors - Supplies the number of sectors to read. Buffer - Returns the read in sectors. Return Value: ArcSeek, ArcRead, EIO, ESUCCESS --*/ { ARC_STATUS r; ULONG c; LARGE_INTEGER l; ULONG i; ULONG transfer; PCHAR buf; ULONG total; l.QuadPart = UInt32x32To64(StartingSector,SectorSize); buf = (PCHAR) Buffer; r = ArcSeek(VolumeId, &l, SeekAbsolute); if (r != ESUCCESS) { return r; } total = SectorSize*NumberOfSectors; for (i = 0; i < total; i += MAX_TRANSFER) { transfer = min(MAX_TRANSFER, total - i); r = ArcRead(VolumeId, &buf[i], transfer, &c); if (r != ESUCCESS) { return r; } if (c != transfer) { return EIO; } } return ESUCCESS; }
ARC_STATUS CdfsReadDisk( IN ULONG DeviceId, IN ULONG Lbo, IN ULONG ByteCount, IN OUT PVOID Buffer ) /*++ Routine Description: This routine reads in zero or more sectors from the specified device. Arguments: DeviceId - Supplies the device id to use in the arc calls. Lbo - Supplies the LBO to start reading from. ByteCount - Supplies the number of bytes to read. Buffer - Supplies a pointer to the buffer to read the bytes into. Return Value: ESUCCESS is returned if the read operation is successful. Otherwise, an unsuccessful status is returned that describes the reason for failure. --*/ { LARGE_INTEGER LargeLbo; ARC_STATUS Status; ULONG i; // // Seek to the appropriate offset on the volume // LargeLbo.LowPart = Lbo; LargeLbo.HighPart = 0; if ((Status = ArcSeek( DeviceId, &LargeLbo , SeekAbsolute )) != ESUCCESS) { return Status; } // // Issue the arc read request // if ((Status = ArcRead( DeviceId, Buffer, ByteCount, &i)) != ESUCCESS) { return Status; } // // Make sure we got back the amount requested // if (ByteCount != i) { return EIO; } // // Everything is fine so return success to our caller // return ESUCCESS; }
BOOLEAN InfOpenFile( PHINF InfHandle, PCSTR FileName, PULONG ErrorLine) { FILEINFORMATION Information; ULONG FileId; PCHAR FileBuffer; ULONG FileSize, Count; PINFCACHE Cache; BOOLEAN Success; LONG ret; *InfHandle = NULL; *ErrorLine = (ULONG) - 1; // // Open the .inf file // FileId = FsOpenFile(FileName); if (!FileId) { return FALSE; } // // Query file size // ret = ArcGetFileInformation(FileId, &Information); if ((ret != ESUCCESS) || (Information.EndingAddress.HighPart != 0)) { ArcClose(FileId); return FALSE; } FileSize = Information.EndingAddress.LowPart; // // Allocate buffer to cache the file // FileBuffer = MmHeapAlloc(FileSize + 1); if (!FileBuffer) { ArcClose(FileId); return FALSE; } // // Read file into memory // ret = ArcRead(FileId, FileBuffer, FileSize, &Count); if ((ret != ESUCCESS) || (Count != FileSize)) { ArcClose(FileId); MmHeapFree(FileBuffer); return FALSE; } // // We don't need the file anymore. Close it // ArcClose(FileId); // // Append string terminator // FileBuffer[FileSize] = 0; // // Allocate infcache header // Cache = (PINFCACHE)MmHeapAlloc(sizeof(INFCACHE)); if (!Cache) { MmHeapFree(FileBuffer); return FALSE; } // // Initialize inicache header // RtlZeroMemory(Cache, sizeof(INFCACHE)); // // Parse the inf buffer // Success = InfpParseBuffer(Cache, FileBuffer, FileBuffer + FileSize, ErrorLine); if (!Success) { MmHeapFree(Cache); Cache = NULL; } // // Free file buffer, as it has been parsed // MmHeapFree(FileBuffer); // // Return .inf parsed contents // *InfHandle = (HINF)Cache; return Success; }
VOID main ( VOID ) /*++ Routine Description: Arguments: None. Return Value: None. --*/ { ULONG Count; UCHAR Character; ARC_STATUS Status; FwRtlStackPanic = 0; VenPrint("Doing a 5 second loop..."); VenStallExecution(1000000); VenPrint("3... "); VenStallExecution(1000000); VenPrint("2... "); VenStallExecution(1000000); VenPrint("1... "); VenStallExecution(1000000); VenPrint("\r\nGO!\r\n"); VenStallExecution(5 * 1000 * 1000); VenPrint("********************* STOP ********************\r\n\n\n"); VenStallExecution(5 * 1000 * 1000); VenPrint("Doing a 10 second loop..."); VenStallExecution(1000000); VenPrint("3... "); VenStallExecution(1000000); VenPrint("2... "); VenStallExecution(1000000); VenPrint("1... "); VenStallExecution(1000000); VenPrint("\r\nGO!\r\n"); VenStallExecution(10 * 1000 * 1000); VenPrint("********************* STOP ********************\r\n\n\n"); VenStallExecution(5 * 1000 * 1000); VenPrint("Doing a 20 second loop..."); VenStallExecution(1000000); VenPrint("3... "); VenStallExecution(1000000); VenPrint("2... "); VenStallExecution(1000000); VenPrint("1... "); VenStallExecution(1000000); VenPrint("\r\nGO!\r\n"); VenStallExecution(20 * 1000 * 1000); VenPrint("********************* STOP ********************\r\n\n\n"); VenStallExecution(5 * 1000 * 1000); VenPrint("Doing a 40 second loop..."); VenStallExecution(1000000); VenPrint("3... "); VenStallExecution(1000000); VenPrint("2... "); VenStallExecution(1000000); VenPrint("1... "); VenStallExecution(1000000); VenPrint("\r\nGO!\r\n"); VenStallExecution(40 * 1000 * 1000); VenPrint("********************* STOP ********************\r\n\n\n"); VenStallExecution(5 * 1000 * 1000); VenPrint("Press any key to return."); if ((Status = ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count)) != ESUCCESS) { VenPrint1("? Can not read keyboard. Status = 0x%x\r\n", Status); VenStallExecution(3000000); } return; }
ARC_STATUS ReadAndVerifyUpdateFile( IN PCHAR PathName, OUT PULONG BufferAddress, OUT PULONG FirmwareStart, OUT PULONG BufferLength, OUT PULONG LowROMBlock, OUT PULONG HighROMBlock ) /*++ Routine Description: This attempts to load and verify the firmware update file. Arguments: PathName A pointer to string descriptor for the name of the file to load. BufferAddress A pointer to a variable that receives the address of the image base. FirmwareStart A pointer to a variable that receives the address of the start of the firmware. This is the first byte after the null byte that terminates the identifier string. BufferLength A pointer to a variable that receives the length of the image. LowROMBlock A pointer to a variable that receives the low ROM block to be updated. HighROMBlock A pointer to a variable that receives the low ROM block to be updated. Return Value: ESUCCESS is returned if the image file is loaded and verified. Otherwise, an unsuccessful status is returned that describes the reason for failure. Additionally, some detailed error messages may be printed out by this function. With any return, the file will have already been closed. --*/ { ULONG ActualBase; ULONG Count; ULONG FileId; ULONG Index; ULONG PageCount; ARC_STATUS Status; LARGE_INTEGER SeekPosition; FILE_INFORMATION FileInfo; ULONG FileSize; CHAR ChecksumAdjustment[4]; ULONG AccumulatedSum; ULONG AmountOfBinaryData; // // Attempt to open the file. // Status = ArcOpen(PathName, ArcOpenReadOnly, &FileId); if (Status != ESUCCESS) { VenPrint(FWUP_READ_CANT_OPEN_MSG); return Status; } // // Get the file information to figure out how big the file is. // Status = ArcGetFileInformation(FileId, &FileInfo); if (Status != ESUCCESS) { VenPrint(FWUP_READ_CANT_GET_FILE_INFO_MSG); ArcClose(FileId); return Status; } FileSize = FileInfo.EndingAddress.LowPart - FileInfo.StartingAddress.LowPart; if ((FileSize < MINIMUM_UPDATE_FILE_SIZE) || (FileSize > MAXIMUM_UPDATE_FILE_SIZE)) { VenPrint(FWUP_READ_BAD_SIZE_MSG); ArcClose(FileId); return EINVAL; } // // Compute number of pages in the file and read it in. // PageCount = (FileSize + PAGE_SIZE - 1) >> PAGE_SHIFT; Status = JnFsAllocateDescriptor(MemoryFree, PageCount, &ActualBase); if (Status != ESUCCESS) { VenPrint1(FWUP_READ_NOT_ENOUGH_MEMORY, PageCount); ArcClose(FileId); return Status; } // // Compute the byte address of the update file buffer // *BufferAddress = KSEG0_BASE | (ActualBase << PAGE_SHIFT); VenPrint(FWUP_READ_READING_MSG); Status = ArcRead(FileId, (PUCHAR)*BufferAddress, FileSize, &Count); ArcClose(FileId); if (Count != FileSize) { VenPrint2(FWUP_READ_BAD_READ_COUNT_MSG, FileSize, Count); if (Status != ESUCCESS) { return Status; } else { return EIO; } } if (Status != ESUCCESS) { return Status; } // // Verify the file's checksum. // VenPrint(FWUP_READ_VERIFYING_CHECKSUM_MSG); AccumulatedSum = 0; Index = 0; do { ChecksumAdjustment[0] = ChecksumAdjustment[1]; ChecksumAdjustment[1] = ChecksumAdjustment[2]; ChecksumAdjustment[2] = ChecksumAdjustment[3]; ChecksumAdjustment[3] = *(((PUCHAR)*BufferAddress)+Index); AccumulatedSum += *(((PUCHAR)*BufferAddress)+Index); Index++; } while (Index < FileSize); // Filesize is 1-based, Index is 0-based // The last four bytes were really a 32-bit additive-zero checksum, // order of {low byte -- high byte } AccumulatedSum = AccumulatedSum - ChecksumAdjustment[3] - ChecksumAdjustment[2] - ChecksumAdjustment[1] - ChecksumAdjustment[0]; AccumulatedSum = AccumulatedSum + ((ChecksumAdjustment[3] << 24) | (ChecksumAdjustment[2] << 16) | (ChecksumAdjustment[1] << 8) | (ChecksumAdjustment[0])); if (AccumulatedSum != 0) { VenPrint1 (FWUP_READ_BAD_CHECKSUM_MSG, AccumulatedSum); return ENOEXEC; } // // The checksum is good. Find the start of the firmware data. // Index = 0; while ((Index < MAXIMUM_IDENTIFIER_LENGTH) && (*(((PUCHAR)*BufferAddress)+Index) != 0)) { Index++; } if (Index == MAXIMUM_IDENTIFIER_LENGTH) { VenPrint(FWUP_READ_IDENTIFIER_TOO_LONG_MSG); return ENOEXEC; } // // Skip over the starting block byte // *FirmwareStart = (ULONG)(((PUCHAR)*BufferAddress) + Index + 2); // // Now verify legality of the starting block number, and verify that // we have at least that much data in the binary section of the file. // *LowROMBlock = *(((PUCHAR)*BufferAddress) + Index + 1); if (*LowROMBlock > 0xf) { VenPrint1(FWUP_READ_BAD_START_BLOCK_MSG, *LowROMBlock); return ENOEXEC; } AmountOfBinaryData = FileSize - (ULONG)((PUCHAR)*FirmwareStart - (PUCHAR)*BufferAddress) - 4; *BufferLength = AmountOfBinaryData; if ((AmountOfBinaryData % SIXTY_FOUR_KB) != 0) { VenPrint(FWUP_READ_BAD_BINARY_DATA_MSG); return EBADF; } *HighROMBlock = *LowROMBlock + (AmountOfBinaryData / SIXTY_FOUR_KB) - 1; if ((*HighROMBlock < *LowROMBlock) || (*HighROMBlock > 0xf)) { VenPrint2(FWUP_READ_TOO_MUCH_DATA_MSG, *LowROMBlock, *HighROMBlock); return E2BIG; } return ESUCCESS; }
GETSTRING_ACTION JzGetString( OUT PCHAR String, IN ULONG StringLength, IN PCHAR InitialString OPTIONAL, IN ULONG CurrentRow, IN ULONG CurrentColumn, IN BOOLEAN ShowTheTime ) /*++ Routine Description: This routine reads a string from standardin until a carriage return is found, StringLength is reached, or ESC is pushed. Semicolons are discarded. Reason: semicolons are key characters in the parsing of multi-segment environment variables. They aren not needed for any valid input to the firmware, so the easiest solution is to filter them here. Arguments: String - Supplies a pointer to a location where the string is to be stored. StringLength - Supplies the Max Length to read. InitialString - Supplies an optional initial string. CurrentRow - Supplies the current screen row. CurrentColumn - Supplies the current screen column. ShowTheTime If true, the time is displayed in the upper right-hand corner of the screen. Return Value: If the string was successfully obtained GetStringSuccess is return, otherwise one of the following codes is returned. GetStringEscape - the escape key was pressed or StringLength was reached. GetStringUpArrow - the up arrow key was pressed. GetStringDownArrow - the down arrow key was pressed. --*/ { ARC_STATUS Status; UCHAR c; ULONG Count; PCHAR Buffer; PCHAR Cursor; PCHAR CopyPointer; GETSTRING_ACTION Action; // // If an initial string was supplied, update the output string. // if (ARGUMENT_PRESENT(InitialString)) { strcpy(String, InitialString); Buffer = strchr(String, 0); } else { *String = 0; Buffer = String; } Cursor = Buffer; while (TRUE) { // // Print the string. // VenSetPosition(CurrentRow, CurrentColumn); VenPrint(String); VenPrint("\x9bK"); // // Print the cursor. // VenSetScreenAttributes(TRUE,FALSE,TRUE); VenSetPosition(CurrentRow, (Cursor - String) + CurrentColumn); if (Cursor >= Buffer) { VenPrint(" "); } else { ArcWrite(ARC_CONSOLE_OUTPUT,Cursor,1,&Count); } VenSetScreenAttributes(TRUE,FALSE,FALSE); #ifndef JNUPDATE while (ShowTheTime && ArcGetReadStatus(ARC_CONSOLE_INPUT) != ESUCCESS) { JzShowTime(FALSE); } #endif Status = ArcRead(ARC_CONSOLE_INPUT,&c,1,&Count); if (Status != ESUCCESS) { Action = GetStringEscape; goto EndGetString; } if (Buffer-String == StringLength) { Action = GetStringEscape; goto EndGetString; } switch (c) { case ASCII_ESC: // // If there is another character available, look to see if // this a control sequence, and fall through to ASCII_CSI. // This is an attempt to make escape sequences from a terminal work. // VenStallExecution(10000); if (ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) { ArcRead(ARC_CONSOLE_INPUT, &c, 1, &Count); if (c != '[') { Action = GetStringEscape; goto EndGetString; } } else { Action = GetStringEscape; goto EndGetString; } case ASCII_CSI: ArcRead(ARC_CONSOLE_INPUT, &c, 1, &Count); switch (c) { case 'A': Action = GetStringUpArrow; goto EndGetString; case 'D': if (Cursor != String) { Cursor--; } continue; case 'B': Action = GetStringDownArrow; goto EndGetString; case 'C': if (Cursor != Buffer) { Cursor++; } continue; case 'H': Cursor = String; continue; case 'K': Cursor = Buffer; continue; case 'P': CopyPointer = Cursor; while (*CopyPointer) { *CopyPointer = *(CopyPointer + 1); CopyPointer++; } if (Buffer != String) { Buffer--; } continue; default: break; } break; case '\r': case '\n': Action = GetStringSuccess; goto EndGetString; // // Do not bother handling the tab character properly. // case '\t' : Action = GetStringEscape; goto EndGetString; case '\b': if (Cursor != String) { Cursor--; } CopyPointer = Cursor; while (*CopyPointer) { *CopyPointer = *(CopyPointer + 1); CopyPointer++; } if (Buffer != String) { Buffer--; } break; // // Discard any semicolons because they will corrupt multi- // segment environment variables. // case ';': break; default: // // Store the character. // CopyPointer = ++Buffer; if (CopyPointer > Cursor) { while (CopyPointer != Cursor) { *CopyPointer = *(CopyPointer - 1); CopyPointer--; } } *Cursor++ = c; break; } } Action = GetStringEscape; EndGetString: VenSetPosition(CurrentRow, (Cursor - String) + CurrentColumn); if (Cursor >= Buffer) { VenPrint(" "); } else { ArcWrite(ARC_CONSOLE_OUTPUT,Cursor,1,&Count); } // // Make sure we return a null string if not successful. // if (Action != GetStringSuccess) { *String = 0; } return(Action); }
/* * WinLdrLoadImage loads the specified image from the file (it doesn't * perform any additional operations on the filename, just directly * calls the file I/O routines), and relocates it so that it's ready * to be used when paging is enabled. * Addressing mode: physical */ BOOLEAN WinLdrLoadImage(IN PCHAR FileName, TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA) { ULONG FileId; PVOID PhysicalBase; PVOID VirtualBase = NULL; UCHAR HeadersBuffer[SECTOR_SIZE * 2]; PIMAGE_NT_HEADERS NtHeaders; PIMAGE_SECTION_HEADER SectionHeader; ULONG VirtualSize, SizeOfRawData, NumberOfSections; ARC_STATUS Status; LARGE_INTEGER Position; ULONG i, BytesRead; TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType); /* Open the image file */ Status = ArcOpen(FileName, OpenReadOnly, &FileId); if (Status != ESUCCESS) { // UiMessageBox("Can not open the file."); return FALSE; } /* Load the first 2 sectors of the image so we can read the PE header */ Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead); if (Status != ESUCCESS) { UiMessageBox("Error reading from file."); ArcClose(FileId); return FALSE; } /* Now read the MZ header to get the offset to the PE Header */ NtHeaders = RtlImageNtHeader(HeadersBuffer); if (!NtHeaders) { // Print(L"Error - no NT header found in %s\n", FileName); UiMessageBox("Error - no NT header found."); ArcClose(FileId); return FALSE; } /* Ensure this is executable image */ if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0)) { // Print(L"Not an executable image %s\n", FileName); UiMessageBox("Not an executable image."); ArcClose(FileId); return FALSE; } /* Store number of sections to read and a pointer to the first section */ NumberOfSections = NtHeaders->FileHeader.NumberOfSections; SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); /* Try to allocate this memory, if fails - allocate somewhere else */ PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage, (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)), MemoryType); if (PhysicalBase == NULL) { /* It's ok, we don't panic - let's allocate again at any other "low" place */ PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType); if (PhysicalBase == NULL) { // Print(L"Failed to alloc pages for image %s\n", FileName); UiMessageBox("Failed to alloc pages for image."); ArcClose(FileId); return FALSE; } } /* This is the real image base - in form of a virtual address */ VirtualBase = PaToVa(PhysicalBase); TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase); /* Set to 0 position and fully load the file image */ Position.HighPart = Position.LowPart = 0; Status = ArcSeek(FileId, &Position, SeekAbsolute); if (Status != ESUCCESS) { UiMessageBox("Error seeking to start of file."); ArcClose(FileId); return FALSE; } Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead); if (Status != ESUCCESS) { // Print(L"Error reading headers %s\n", FileName); UiMessageBox("Error reading headers."); ArcClose(FileId); return FALSE; } /* Reload the NT Header */ NtHeaders = RtlImageNtHeader(PhysicalBase); /* Load the first section */ SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); /* Fill output parameters */ *ImageBasePA = PhysicalBase; /* Walk through each section and read it (check/fix any possible bad situations, if they arise) */ for (i = 0; i < NumberOfSections; i++) { VirtualSize = SectionHeader->Misc.VirtualSize; SizeOfRawData = SectionHeader->SizeOfRawData; /* Handle a case when VirtualSize equals 0 */ if (VirtualSize == 0) VirtualSize = SizeOfRawData; /* If PointerToRawData is 0, then force its size to be also 0 */ if (SectionHeader->PointerToRawData == 0) { SizeOfRawData = 0; } else { /* Cut the loaded size to the VirtualSize extents */ if (SizeOfRawData > VirtualSize) SizeOfRawData = VirtualSize; } /* Actually read the section (if its size is not 0) */ if (SizeOfRawData != 0) { /* Seek to the correct position */ Position.LowPart = SectionHeader->PointerToRawData; Status = ArcSeek(FileId, &Position, SeekAbsolute); TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress); /* Read this section from the file, size = SizeOfRawData */ Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead); if (Status != ESUCCESS) { ERR("WinLdrLoadImage(): Error reading section from file!\n"); break; } } /* Size of data is less than the virtual size - fill up the remainder with zeroes */ if (SizeOfRawData < VirtualSize) { TRACE("WinLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize); RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData); } SectionHeader++; } /* We are done with the file - close it */ ArcClose(FileId); /* If loading failed - return right now */ if (Status != ESUCCESS) return FALSE; /* Relocate the image, if it needs it */ if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase) { WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, VirtualBase); return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase, (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase, "FreeLdr", TRUE, TRUE, /* in case of conflict still return success */ FALSE); } TRACE("WinLdrLoadImage() done, PA = %p\n", *ImageBasePA); return TRUE; }
VOID BlGetActivePartition( OUT PUCHAR BootPartitionName ) /*++ Routine Description: Determine the ARC name for the partition NTLDR was started from Arguments: BootPartitionName - Supplies a buffer where the ARC name of the partition will be returned. Return Value: Name of the partition is in BootPartitionName. Must always succeed. --*/ { UCHAR SectorBuffer[512]; UCHAR NameBuffer[80]; ARC_STATUS Status; ULONG FileId; ULONG Count; int i; // // The method we use is to open each partition on the first drive // and read in its boot sector. Then we compare that to the boot // sector that we used to boot from (at physical address 0x7c00. // If they are the same, we've found it. If we run out of partitions, // just try partition 1 // i=1; do { sprintf(NameBuffer, "multi(0)disk(0)rdisk(0)partition(%u)",i); Status = ArcOpen(NameBuffer,ArcOpenReadOnly,&FileId); if (Status != ESUCCESS) { // // we've run out of partitions, return the default. // i=1; break; } else { // // Read in the first 512 bytes // Status = ArcRead(FileId, SectorBuffer, 512, &Count); ArcClose(FileId); if (Status==ESUCCESS) { // // only need to compare the first 36 bytes // Jump instr. == 3 bytes // Oem field == 8 bytes // BPB == 25 bytes // if (memcmp(SectorBuffer, (PVOID)0x7c00, 36)==0) { // // we have found a match. // break; } } } ++i; } while ( TRUE ); sprintf(BootPartitionName, "multi(0)disk(0)rdisk(0)partition(%u)",i); return; }
VOID BlpRebootDOS( IN PCHAR BootSectorImage OPTIONAL ) /*++ Routine Description: Loads up the bootstrap sectors and executes them (thereby rebooting into DOS or OS/2) Arguments: BootSectorImage - If specified, supplies name of file on the C: drive that contains the boot sector image. In this case, this routine will return if that file cannot be opened (for example, if it's a directory). If not specified, then default to \bootsect.dos, and this routine will never return. Return Value: None. --*/ { ULONG SectorId; ARC_STATUS Status; ULONG Read; ULONG DriveId; ULONG BootType; LARGE_INTEGER SeekPosition; extern UCHAR BootPartitionName[]; // // HACKHACK John Vert (jvert) // Some SCSI drives get really confused and return zeroes when // you use the BIOS to query their size after the AHA driver has // initialized. This can completely tube OS/2 or DOS. So here // we try and open both BIOS-accessible hard drives. Our open // code is smart enough to retry if it gets back zeros, so hopefully // this will give the SCSI drives a chance to get their act together. // Status = ArcOpen("multi(0)disk(0)rdisk(0)partition(0)", ArcOpenReadOnly, &DriveId); if (Status == ESUCCESS) { ArcClose(DriveId); } Status = ArcOpen("multi(0)disk(0)rdisk(1)partition(0)", ArcOpenReadOnly, &DriveId); if (Status == ESUCCESS) { ArcClose(DriveId); } // // Load the boot sector at address 0x7C00 (expected by Reboot callback) // Status = ArcOpen(BootPartitionName, ArcOpenReadOnly, &DriveId); if (Status != ESUCCESS) { BlPrint(BlFindMessage(BL_REBOOT_IO_ERROR),BootPartitionName); while (1) { GET_KEY(); } } Status = BlOpen( DriveId, BootSectorImage ? BootSectorImage : "\\bootsect.dos", ArcOpenReadOnly, &SectorId ); if (Status != ESUCCESS) { if(BootSectorImage) { // // The boot sector image might actually be a directory. // Return to the caller to attempt standard boot. // BlClose(DriveId); return; } BlPrint(BlFindMessage(BL_REBOOT_IO_ERROR),BootPartitionName); while (1) { } } Status = BlRead( SectorId, (PVOID)0x7c00, SECTOR_SIZE, &Read ); if (Status != ESUCCESS) { BlPrint(BlFindMessage(BL_REBOOT_IO_ERROR),BootPartitionName); while (1) { } } // // The FAT boot code is only one sector long so we just want // to load it up and jump to it. // // For HPFS and NTFS, we can't do this because the first sector // loads the rest of the boot sectors -- but we want to use // the boot code in the boot sector image file we loaded. // // For HPFS, we load the first 20 sectors (boot code + super and // space blocks) into d00:200. Fortunately this works for both // NT and OS/2. // // For NTFS, we load the first 16 sectors and jump to d00:256. // If the OEM field of the boot sector starts with NTFS, we // assume it's NTFS boot code. // // // Try to read 8K from the boot code image. // If this succeeds, we have either HPFS or NTFS. // SeekPosition.QuadPart = 0; BlSeek(SectorId,&SeekPosition,SeekAbsolute); BlRead(SectorId,(PVOID)0xd000,SECTOR_SIZE*16,&Read); if(Read == SECTOR_SIZE*16) { if(memcmp((PVOID)0x7c03,"NTFS",4)) { // // HPFS -- we need to load the super block. // BootType = 1; // HPFS SeekPosition.QuadPart = 16*SECTOR_SIZE; ArcSeek(DriveId,&SeekPosition,SeekAbsolute); ArcRead(DriveId,(PVOID)0xf000,SECTOR_SIZE*4,&Read); } else { // // NTFS -- we've loaded everything we need to load. // BootType = 2; // NTFS } } else { BootType = 0; // FAT } // // DX must be the drive to boot from // _asm { mov dx, 0x80 } REBOOT(BootType); }