// MapPhysicalMemory // Maps a view of a section. // BOOLEAN MapPhysicalMemory( HANDLE PhysicalMemory, PDWORD Address, PDWORD Length, PDWORD VirtualAddress ) { NTSTATUS ntStatus; PHYSICAL_ADDRESS viewBase; // char error[256]; *VirtualAddress = 0; viewBase.QuadPart = (ULONGLONG) (*Address); ntStatus = NtMapViewOfSection (PhysicalMemory, (HANDLE)-1, (PVOID *)VirtualAddress, 0L, *Length, &viewBase, Length, ViewShare, 0, PAGE_READONLY ); if( !NT_SUCCESS( ntStatus )) { // sprintf( error, "Could not map view of %X length %X", // *Address, *Length ); // PrintError( error, ntStatus ); return FALSE; } *Address = viewBase.LowPart; return TRUE; }
static int devmem_map(HANDLE h, off64_t *addr, PDWORD len, PDWORD vaddr, int oflags) { NTSTATUS r; PHYSICAL_ADDRESS base; unsigned long am; switch(oflags & O_ACCMODE) { case O_RDONLY: am = PAGE_READONLY; break; case O_WRONLY: case O_RDWR: am = PAGE_READWRITE; break; } *vaddr = 0; base.QuadPart = (ULONGLONG) *addr; r = NtMapViewOfSection(h, (HANDLE) -1, (PVOID) vaddr, 0, *len, &base, len, ViewShare, 0, am); if(!NT_SUCCESS(r)) { logerr(0, "NtMapViewOfSection failed"); errno = unix_err(RtlNtStatusToDosError(r)); return 0; } *addr = base.QuadPart; return 1; }
/*********************************************************************** * MapViewOfFileEx (KERNEL32.@) * * Maps a view of a file into the address space. * * PARAMS * handle [I] File-mapping object to map. * access [I] Access mode. * offset_high [I] High-order 32 bits of file offset. * offset_low [I] Low-order 32 bits of file offset. * count [I] Number of bytes to map. * addr [I] Suggested starting address for mapped view. * * RETURNS * Success: Starting address of mapped view. * Failure: NULL. */ LPVOID WINAPI MapViewOfFileEx( HANDLE handle, DWORD access, DWORD offset_high, DWORD offset_low, SIZE_T count, LPVOID addr ) { NTSTATUS status; LARGE_INTEGER offset; ULONG protect; BOOL exec; offset.u.LowPart = offset_low; offset.u.HighPart = offset_high; exec = access & FILE_MAP_EXECUTE; access &= ~FILE_MAP_EXECUTE; if (access == FILE_MAP_COPY) protect = exec ? PAGE_EXECUTE_WRITECOPY : PAGE_WRITECOPY; else if (access & FILE_MAP_WRITE) protect = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; else if (access & FILE_MAP_READ) protect = exec ? PAGE_EXECUTE_READ : PAGE_READONLY; else protect = PAGE_NOACCESS; if ((status = NtMapViewOfSection( handle, GetCurrentProcess(), &addr, 0, 0, &offset, &count, ViewShare, 0, protect )) < 0) { SetLastError( RtlNtStatusToDosError(status) ); addr = NULL; } return addr; }
static int OnMapViewClick(HWND hDlg) { TFileTestData * pData = GetDialogData(hDlg); LARGE_INTEGER SectionOffset; NTSTATUS Status; SIZE_T ViewSize; PVOID BaseAddress; // If we have mapped view, unmap it now if(pData->bSectionViewMapped) OnUnmapViewClick(hDlg); // Get the values from dialog controls to the dialog data if(SaveDialog2(hDlg) != ERROR_SUCCESS) return FALSE; // Copy some values to stack SectionOffset.QuadPart = pData->SectionOffset.QuadPart; BaseAddress = pData->pvSectionMappedView; ViewSize = pData->cbSectViewSize; // Call the NtMapViewOfSection Status = NtMapViewOfSection(pData->hSection, NtCurrentProcess(), &BaseAddress, 0, pData->cbSectCommitSize, &SectionOffset, &ViewSize, ViewShare, pData->dwSectAllocType, pData->dwSectWin32Protect); if(NT_SUCCESS(Status)) { // If the section offset changed, set it to the dialog control if(SectionOffset.QuadPart != pData->SectionOffset.QuadPart) Hex2DlgText64(hDlg, IDC_SECTION_OFFSET, SectionOffset.QuadPart); if(BaseAddress != pData->pvSectionMappedView) Hex2DlgTextPtr(hDlg, IDC_BASE_ADDRESS, (ULONG_PTR)BaseAddress); if(ViewSize != pData->cbSectViewSize) Hex2DlgTextPtr(hDlg, IDC_VIEW_SIZE, ViewSize); // Remember the view pData->pvSectionMappedView = BaseAddress; pData->cbSectViewSize = ViewSize; pData->bSectionViewMapped = TRUE; } SetResultInfo(hDlg, Status, pData->hSection); UpdateDialog(hDlg, pData); return TRUE; }
/* * @implemented */ BOOL WINAPI Process32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe) { PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status; CHECK_PARAM_SIZE(lppe, sizeof(PROCESSENTRY32W)); SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL; Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret; if(Snapshot->ProcessListCount > 0) { LPPROCESSENTRY32W Entries = (LPPROCESSENTRY32W)OffsetToPtr(Snapshot, Snapshot->ProcessListOffset); Snapshot->ProcessListIndex = 1; RtlCopyMemory(lppe, &Entries[0], sizeof(PROCESSENTRY32W)); Ret = TRUE; } else { SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; } NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; } BaseSetLastNTError(Status); return FALSE; }
/* * SfuCreateFileMappingNoExec * * Purpose: * * Map file as non executable image. * */ PVOID SfuCreateFileMappingNoExec( _In_ LPWSTR lpFileName ) { BOOL cond = FALSE; NTSTATUS status; UNICODE_STRING usFileName; HANDLE hFile = NULL, hSection = NULL; OBJECT_ATTRIBUTES obja; IO_STATUS_BLOCK iost; SIZE_T ViewSize = 0; PVOID Data = NULL; RtlSecureZeroMemory(&usFileName, sizeof(usFileName)); do { if (RtlDosPathNameToNtPathName_U(lpFileName, &usFileName, NULL, NULL) == FALSE) break; InitializeObjectAttributes(&obja, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); status = NtOpenFile(&hFile, FILE_READ_ACCESS | SYNCHRONIZE, &obja, &iost, FILE_SHARE_READ, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(status)) break; status = NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, NULL, PAGE_READONLY, SEC_IMAGE_NO_EXECUTE, hFile); if (!NT_SUCCESS(status)) break; status = NtMapViewOfSection(hSection, NtCurrentProcess(), (PVOID)&Data, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY); if (!NT_SUCCESS(status)) break; } while (cond); if (hFile != NULL) { NtClose(hFile); } if (hSection != NULL) { NtClose(hSection); } if (usFileName.Buffer != NULL) { RtlFreeUnicodeString(&usFileName); } return Data; }
int console_fork(HANDLE process) { log_info("Mapping console shared memory region to child process...\n"); PVOID base_addr = console; SIZE_T view_size = sizeof(struct console_data); NTSTATUS status; status = NtMapViewOfSection(console->section, process, &base_addr, 0, sizeof(struct console_data), NULL, &view_size, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(status)) { log_error("NtMapViewOfSection() failed, status: %x\n", status); return 0; } return 1; }
/* * @implemented */ BOOL WINAPI Heap32ListNext(HANDLE hSnapshot, LPHEAPLIST32 lphl) { PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status; CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32)); SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL; Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret; if(Snapshot->HeapListCount > 0 && Snapshot->HeapListIndex < Snapshot->HeapListCount) { LPHEAPLIST32 Entries = (LPHEAPLIST32)OffsetToPtr(Snapshot, Snapshot->HeapListOffset); RtlCopyMemory(lphl, &Entries[Snapshot->HeapListIndex++], sizeof(HEAPLIST32)); Ret = TRUE; } else { SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; } NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; } BaseSetLastNTError(Status); return FALSE; }
int console_fork(HANDLE process) { log_info("Mapping console shared memory region to child process...\n"); PVOID base_addr = NULL; SIZE_T view_size = sizeof(struct console_data); NTSTATUS status; status = NtMapViewOfSection(console->section, process, &base_addr, 0, sizeof(struct console_data), NULL, &view_size, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE); if (!NT_SUCCESS(status)) { log_error("NtMapViewOfSection() failed, status: %x\n", status); return 0; } if (!WriteProcessMemory(process, &console, &base_addr, sizeof(PVOID), NULL)) { log_error("WriteProcessMemory() failed, error code: %d\n", GetLastError()); return 0; } return 1; }
VOID GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData, BOOL Defaults) { NTSTATUS Status; PCONSRV_CONSOLE Console = GuiData->Console; PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; PCONSOLE_PROCESS_DATA ProcessData; HANDLE hSection = NULL, hClientSection = NULL; LARGE_INTEGER SectionSize; ULONG ViewSize = 0; SIZE_T Length = 0; PCONSOLE_PROPS pSharedInfo = NULL; PGUI_CONSOLE_INFO GuiInfo = NULL; DPRINT("GuiConsoleShowConsoleProperties entered\n"); if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return; /* * Create a memory section to share with the applet, and map it. */ /* Holds data for console.dll + console info + terminal-specific info */ SectionSize.QuadPart = sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO); Status = NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &SectionSize, PAGE_READWRITE, SEC_COMMIT, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status); goto Quit; } Status = NtMapViewOfSection(hSection, NtCurrentProcess(), (PVOID*)&pSharedInfo, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status); goto Quit; } /* * Setup the shared console properties structure. */ /* Header */ pSharedInfo->hConsoleWindow = GuiData->hWindow; pSharedInfo->ShowDefaultParams = Defaults; /* * We fill-in the fields only if we display * our properties, not the default ones. */ if (!Defaults) { /* Console information */ pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize; pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup; pSharedInfo->ci.QuickEdit = Console->QuickEdit; pSharedInfo->ci.InsertMode = Console->InsertMode; /////////////pSharedInfo->ci.InputBufferSize = 0; pSharedInfo->ci.ScreenBufferSize = ActiveBuffer->ScreenBufferSize; pSharedInfo->ci.ConsoleSize = ActiveBuffer->ViewSize; pSharedInfo->ci.CursorBlinkOn; pSharedInfo->ci.ForceCursorOff; pSharedInfo->ci.CursorSize = ActiveBuffer->CursorInfo.dwSize; if (GetType(ActiveBuffer) == TEXTMODE_BUFFER) { PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer; pSharedInfo->ci.ScreenAttrib = Buffer->ScreenDefaultAttrib; pSharedInfo->ci.PopupAttrib = Buffer->PopupDefaultAttrib; } else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) { // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer; DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n"); // FIXME: Gather defaults from the registry ? pSharedInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB; pSharedInfo->ci.PopupAttrib = DEFAULT_POPUP_ATTRIB ; } pSharedInfo->ci.CodePage; /* GUI Information */ pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO); GuiInfo = pSharedInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pSharedInfo + 1); wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE); GuiInfo->FaceName[LF_FACESIZE - 1] = UNICODE_NULL; GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily; GuiInfo->FontSize = GuiData->GuiInfo.FontSize; GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight; GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen; GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition; GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin; /* Offsetize */ pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)GuiInfo - (ULONG_PTR)pSharedInfo); /* Palette */ memcpy(pSharedInfo->ci.Colors, Console->Colors, sizeof(Console->Colors)); /* Title of the console, original one corresponding to the one set by the console leader */ Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) / sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1, Console->OriginalTitle.Length / sizeof(WCHAR)); wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length); } else { Length = 0; // FIXME: Load the default parameters from the registry. } /* Null-terminate the title */ pSharedInfo->ci.ConsoleTitle[Length] = L'\0'; /* Unmap the view */ NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo); /* Get the console leader process, our client */ ProcessData = ConSrvGetConsoleLeaderProcess(Console); /* Duplicate the section handle for the client */ Status = NtDuplicateObject(NtCurrentProcess(), hSection, ProcessData->Process->ProcessHandle, &hClientSection, 0, 0, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(Status)) { DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status); goto Quit; } /* Start the properties dialog */ if (ProcessData->PropRoutine) { _SEH2_TRY { HANDLE Thread = NULL; _SEH2_TRY { Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0, ProcessData->PropRoutine, (PVOID)hClientSection, 0, NULL); if (NULL == Thread) { DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError()); } else { DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process); /// WaitForSingleObject(Thread, INFINITE); } } _SEH2_FINALLY { CloseHandle(Thread); } _SEH2_END; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status); } _SEH2_END; }
VOID GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData, HANDLE hClientSection, BOOL SaveSettings) { NTSTATUS Status = STATUS_SUCCESS; PCONSRV_CONSOLE Console = GuiData->Console; PCONSOLE_PROCESS_DATA ProcessData; HANDLE hSection = NULL; ULONG ViewSize = 0; PCONSOLE_PROPS pConInfo = NULL; PCONSOLE_INFO ConInfo = NULL; PTERMINAL_INFO TermInfo = NULL; PGUI_CONSOLE_INFO GuiInfo = NULL; if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return; /* Get the console leader process, our client */ ProcessData = ConSrvGetConsoleLeaderProcess(Console); /* Duplicate the section handle for ourselves */ Status = NtDuplicateObject(ProcessData->Process->ProcessHandle, hClientSection, NtCurrentProcess(), &hSection, 0, 0, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(Status)) { DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status); goto Quit; } /* Get a view of the shared section */ Status = NtMapViewOfSection(hSection, NtCurrentProcess(), (PVOID*)&pConInfo, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status); goto Quit; } _SEH2_TRY { /* Check that the section is well-sized */ if ( (ViewSize < sizeof(CONSOLE_PROPS)) || (pConInfo->TerminalInfo.Size != sizeof(GUI_CONSOLE_INFO)) || (ViewSize < sizeof(CONSOLE_PROPS) + pConInfo->TerminalInfo.Size) ) { DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n"); Status = STATUS_INVALID_VIEW_SIZE; _SEH2_YIELD(goto Quit); } // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow /* Retrieve terminal informations */ ConInfo = &pConInfo->ci; TermInfo = &pConInfo->TerminalInfo; GuiInfo = TermInfo->TermInfo = (PVOID)((ULONG_PTR)pConInfo + (ULONG_PTR)TermInfo->TermInfo); /* * If we don't set the default parameters, * apply them, otherwise just save them. */ if (pConInfo->ShowDefaultParams == FALSE) { /* Set the console informations */ ConSrvApplyUserSettings(Console, ConInfo); /* Set the terminal informations */ // memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO)); /* Change the font */ InitFonts(GuiData, GuiInfo->FaceName, GuiInfo->FontFamily, GuiInfo->FontSize, GuiInfo->FontWeight); // HACK, needed because changing font may change the size of the window /**/TermResizeTerminal(Console);/**/ /* Move the window to the user's values */ GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition; GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin; GuiConsoleMoveWindow(GuiData); InvalidateRect(GuiData->hWindow, NULL, TRUE); /* * Apply full-screen mode. */ if (GuiInfo->FullScreen != GuiData->GuiInfo.FullScreen) { SwitchFullScreen(GuiData, GuiInfo->FullScreen); } } /* * Save settings if needed */ // FIXME: Do it in the console properties applet ?? if (SaveSettings) { DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess); ConSrvWriteUserSettings(ConInfo, ProcessId); GuiConsoleWriteUserSettings(GuiInfo, ConInfo->ConsoleTitle, ProcessId); } Status = STATUS_SUCCESS; }
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { static WCHAR dll_exist[] = L"ITH_DLL_RUNNING"; static HANDLE hDllExist; switch (fdwReason) { case DLL_PROCESS_ATTACH: { LdrDisableThreadCalloutsForDll(hinstDLL); IthBreak(); module_base = (DWORD)hinstDLL; IthInitSystemService(); DWORD s; swprintf(hm_section,L"ITH_SECTION_%d",current_process_id); hSection=IthCreateSection(hm_section,0x2000,PAGE_EXECUTE_READWRITE); NtMapViewOfSection(hSection,NtCurrentProcess(),(PVOID*)&hookman,0, hook_buff_len,0,&hook_buff_len,ViewUnmap,0,PAGE_EXECUTE_READWRITE); LPWSTR p; for (p = GetMainModulePath(); *p; p++); for (p = p; *p != L'\\'; p--); wcscpy(dll_name,p+1); //swprintf(dll_mutex,L"ITH_%.4d_%s",current_process_id,current_dir); swprintf(dll_mutex,L"ITH_%d",current_process_id); swprintf(hm_mutex,L"ITH_HOOKMAN_%d",current_process_id); hmMutex=IthCreateMutex(hm_mutex,0); hMutex=IthCreateMutex(dll_mutex,1,&s); if (s) return FALSE; hDllExist = IthCreateMutex(dll_exist, 0); hDLL=hinstDLL; running=true; current_available=hookman; GetFunctionNames(); InitFilterTable(); InitDefaultHook(); hSendThread=IthCreateThread(WaitForPipe,0); hCmdThread=IthCreateThread(CommandPipe,0); } break; case DLL_PROCESS_DETACH: { running=false; live=false; NtWaitForSingleObject(hSendThread,0,0); NtWaitForSingleObject(hCmdThread,0,0); NtClose(hCmdThread); NtClose(hSendThread); for (TextHook* man=hookman;man->RemoveHook();man++); LARGE_INTEGER lint={-10000,-1}; while (enter_count) NtDelayExecution(0,&lint); for (TextHook* man=hookman;man<hookman+MAX_HOOK;man++) man->ClearHook(); NtUnmapViewOfSection(NtCurrentProcess(),hookman); NtClose(hSection); NtClose(hMutex); delete tree; IthCloseSystemService(); NtClose(hmMutex); NtClose(hDllExist); break; } default: break; } return TRUE; }
PPH_LIST QueryDotNetAppDomainsForPid_V4( _In_ BOOLEAN Wow64, _In_ HANDLE ProcessHandle, _In_ HANDLE ProcessId ) { HANDLE legacyPrivateBlockHandle = NULL; PVOID ipcControlBlockTable = NULL; LARGE_INTEGER sectionOffset = { 0 }; SIZE_T viewSize = 0; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING sectionNameUs; PPH_LIST appDomainsList = NULL; if (!PhStringRefToUnicodeString(&GeneratePrivateNameV4(ProcessId)->sr, §ionNameUs)) goto CleanupExit; InitializeObjectAttributes( &objectAttributes, §ionNameUs, OBJ_CASE_INSENSITIVE, NULL, NULL ); if (!NT_SUCCESS(NtOpenSection( &legacyPrivateBlockHandle, SECTION_MAP_READ, &objectAttributes ))) { goto CleanupExit; } if (!NT_SUCCESS(NtMapViewOfSection( legacyPrivateBlockHandle, NtCurrentProcess(), &ipcControlBlockTable, 0, viewSize, §ionOffset, &viewSize, ViewShare, 0, PAGE_READONLY ))) { goto CleanupExit; } if (Wow64) { LegacyPrivateIPCControlBlock_Wow64* legacyPrivateBlock; AppDomainEnumerationIPCBlock_Wow64* appDomainEnumBlock; legacyPrivateBlock = (LegacyPrivateIPCControlBlock_Wow64*)ipcControlBlockTable; appDomainEnumBlock = &legacyPrivateBlock->AppDomainBlock; // Check the IPCControlBlock is initialized. if ((legacyPrivateBlock->FullIPCHeader.Header.Flags & IPC_FLAG_INITIALIZED) != IPC_FLAG_INITIALIZED) { goto CleanupExit; } // Check the IPCControlBlock version is valid. if (legacyPrivateBlock->FullIPCHeader.Header.Version > VER_LEGACYPRIVATE_IPC_BLOCK) { goto CleanupExit; } appDomainsList = EnumerateAppDomainIpcBlockWow64( ProcessHandle, appDomainEnumBlock ); } else { LegacyPrivateIPCControlBlock* legacyPrivateBlock; AppDomainEnumerationIPCBlock* appDomainEnumBlock; legacyPrivateBlock = (LegacyPrivateIPCControlBlock*)ipcControlBlockTable; appDomainEnumBlock = &legacyPrivateBlock->AppDomainBlock; // Check the IPCControlBlock is initialized. if ((legacyPrivateBlock->FullIPCHeader.Header.Flags & IPC_FLAG_INITIALIZED) != IPC_FLAG_INITIALIZED) { goto CleanupExit; } // Check the IPCControlBlock version is valid. if (legacyPrivateBlock->FullIPCHeader.Header.Version > VER_LEGACYPRIVATE_IPC_BLOCK) { goto CleanupExit; } appDomainsList = EnumerateAppDomainIpcBlock( ProcessHandle, appDomainEnumBlock ); } CleanupExit: if (ipcControlBlockTable) { NtUnmapViewOfSection(NtCurrentProcess(), ipcControlBlockTable); } if (legacyPrivateBlockHandle) { NtClose(legacyPrivateBlockHandle); } return appDomainsList; }
NTSTATUS PhMapViewOfEntireFile( _In_opt_ PWSTR FileName, _In_opt_ HANDLE FileHandle, _In_ BOOLEAN ReadOnly, _Out_ PVOID *ViewBase, _Out_ PSIZE_T Size ) { NTSTATUS status; BOOLEAN openedFile = FALSE; LARGE_INTEGER size; HANDLE sectionHandle = NULL; SIZE_T viewSize; PVOID viewBase; if (!FileName && !FileHandle) return STATUS_INVALID_PARAMETER_MIX; // Open the file if we weren't supplied a file handle. if (!FileHandle) { status = PhCreateFileWin32( &FileHandle, FileName, ((FILE_EXECUTE | FILE_READ_ATTRIBUTES | FILE_READ_DATA) | (!ReadOnly ? (FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA) : 0)) | SYNCHRONIZE, 0, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (!NT_SUCCESS(status)) return status; openedFile = TRUE; } // Get the file size and create the section. status = PhGetFileSize(FileHandle, &size); if (!NT_SUCCESS(status)) goto CleanupExit; status = NtCreateSection( §ionHandle, SECTION_ALL_ACCESS, NULL, &size, ReadOnly ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE, SEC_COMMIT, FileHandle ); if (!NT_SUCCESS(status)) goto CleanupExit; // Map the section. viewSize = (SIZE_T)size.QuadPart; viewBase = NULL; status = NtMapViewOfSection( sectionHandle, NtCurrentProcess(), &viewBase, 0, 0, NULL, &viewSize, ViewShare, 0, ReadOnly ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE ); if (!NT_SUCCESS(status)) goto CleanupExit; *ViewBase = viewBase; *Size = (SIZE_T)size.QuadPart; CleanupExit: if (sectionHandle) NtClose(sectionHandle); if (openedFile) NtClose(FileHandle); return status; }
void console_init() { log_info("Initializing console shared memory region.\n"); /* TODO: mm_mmap() does not support MAP_SHARED yet */ HANDLE section; LARGE_INTEGER section_size; section_size.QuadPart = sizeof(struct console_data); OBJECT_ATTRIBUTES obj_attr; obj_attr.Length = sizeof(OBJECT_ATTRIBUTES); obj_attr.RootDirectory = NULL; obj_attr.ObjectName = NULL; obj_attr.Attributes = OBJ_INHERIT; obj_attr.SecurityDescriptor = NULL; obj_attr.SecurityQualityOfService = NULL; NTSTATUS status; status = NtCreateSection(§ion, SECTION_MAP_READ | SECTION_MAP_WRITE, &obj_attr, §ion_size, PAGE_READWRITE, SEC_COMMIT, NULL); if (!NT_SUCCESS(status)) { log_error("NtCreateSection() failed, status: %x\n", status); return; } PVOID base_addr = console; SIZE_T view_size = sizeof(struct console_data); status = NtMapViewOfSection(section, NtCurrentProcess(), &base_addr, 0, sizeof(struct console_data), NULL, &view_size, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(status)) { log_error("NtMapViewOfSection() failed, status: %x\n", status); return; } SECURITY_ATTRIBUTES attr; attr.nLength = sizeof(SECURITY_ATTRIBUTES); attr.lpSecurityDescriptor = NULL; attr.bInheritHandle = TRUE; HANDLE mutex = CreateMutexW(&attr, FALSE, NULL); if (mutex == NULL) { log_error("CreateMutexW() failed, error code: %d\n", GetLastError()); return; } HANDLE in = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &attr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (in == INVALID_HANDLE_VALUE) { log_error("CreateFile(\"CONIN$\") failed, error code: %d\n", GetLastError()); return; } HANDLE out = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &attr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (out == INVALID_HANDLE_VALUE) { log_error("CreateFile(\"CONOUT$\") failed, error code: %d\n", GetLastError()); return; } console->section = section; console->mutex = mutex; console->in = in; console->out = out; console->termios.c_iflag = INLCR | ICRNL; console->termios.c_oflag = ONLCR | OPOST; console->termios.c_cflag = 0; console->termios.c_lflag = ICANON | ECHO | ECHOCTL; memset(console->termios.c_cc, 0, sizeof(console->termios.c_cc)); console->termios.c_cc[VINTR] = 3; console->termios.c_cc[VERASE] = 8; console->termios.c_cc[VEOF] = 4; console->termios.c_cc[VSUSP] = 26; console->bright = 0; console->reverse = 0; console->foreground = 7; console->background = 0; console->insert_mode = 0; console->cursor_key_mode = 0; console->origin_mode = 0; console->wraparound_mode = 1; /* Only essential values are initialized here, others are automatically set to the correct value in console_retrieve_state() */ console->at_right_margin = 0; console->top = 0; console->scroll_full_screen = 1; console->input_buffer_head = console->input_buffer_tail = 0; console->processor = NULL; SetConsoleMode(in, 0); SetConsoleMode(out, ENABLE_PROCESSED_OUTPUT); log_info("Console shared memory region successfully initialized.\n"); }
BOOLEAN WepCreateServerObjects( VOID ) { OBJECT_ATTRIBUTES objectAttributes; WCHAR buffer[256]; UNICODE_STRING objectName; if (!WeServerSharedSection) { LARGE_INTEGER maximumSize; WeFormatLocalObjectName(WE_SERVER_SHARED_SECTION_NAME, buffer, &objectName); InitializeObjectAttributes(&objectAttributes, &objectName, OBJ_CASE_INSENSITIVE, NULL, NULL); maximumSize.QuadPart = sizeof(WE_HOOK_SHARED_DATA); if (!NT_SUCCESS(NtCreateSection( &WeServerSharedSection, SECTION_ALL_ACCESS, &objectAttributes, &maximumSize, PAGE_READWRITE, SEC_COMMIT, NULL ))) { return FALSE; } } if (!WeServerSharedData) { PVOID viewBase; SIZE_T viewSize; viewBase = NULL; viewSize = sizeof(WE_HOOK_SHARED_DATA); if (!NT_SUCCESS(NtMapViewOfSection( WeServerSharedSection, NtCurrentProcess(), &viewBase, 0, 0, NULL, &viewSize, ViewShare, 0, PAGE_READWRITE ))) { WepCloseServerObjects(); return FALSE; } WeServerSharedData = viewBase; } if (!WeServerSharedSectionLock) { WeFormatLocalObjectName(WE_SERVER_SHARED_SECTION_LOCK_NAME, buffer, &objectName); InitializeObjectAttributes(&objectAttributes, &objectName, OBJ_CASE_INSENSITIVE, NULL, NULL); if (!NT_SUCCESS(NtCreateMutant( &WeServerSharedSectionLock, MUTANT_ALL_ACCESS, &objectAttributes, FALSE ))) { WepCloseServerObjects(); return FALSE; } } if (!WeServerSharedSectionEvent) { WeFormatLocalObjectName(WE_SERVER_SHARED_SECTION_EVENT_NAME, buffer, &objectName); InitializeObjectAttributes(&objectAttributes, &objectName, OBJ_CASE_INSENSITIVE, NULL, NULL); if (!NT_SUCCESS(NtCreateEvent( &WeServerSharedSectionEvent, EVENT_ALL_ACCESS, &objectAttributes, NotificationEvent, FALSE ))) { WepCloseServerObjects(); return FALSE; } } return TRUE; }
NTSTATUS SetupCopyFile( PWCHAR SourceFileName, PWCHAR DestinationFileName) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE FileHandleSource; HANDLE FileHandleDest; static IO_STATUS_BLOCK IoStatusBlock; FILE_STANDARD_INFORMATION FileStandard; FILE_BASIC_INFORMATION FileBasic; ULONG RegionSize; UNICODE_STRING FileName; NTSTATUS Status; PVOID SourceFileMap = 0; HANDLE SourceFileSection; SIZE_T SourceSectionSize = 0; LARGE_INTEGER ByteOffset; #ifdef __REACTOS__ RtlInitUnicodeString(&FileName, SourceFileName); InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile(&FileHandleSource, GENERIC_READ, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SEQUENTIAL_ONLY); if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName); goto done; } #else FileHandleSource = CreateFileW(SourceFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (FileHandleSource == INVALID_HANDLE_VALUE) { Status = STATUS_UNSUCCESSFUL; goto done; } #endif Status = NtQueryInformationFile(FileHandleSource, &IoStatusBlock, &FileStandard, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!NT_SUCCESS(Status)) { DPRINT1("NtQueryInformationFile failed: %x\n", Status); goto closesrc; } Status = NtQueryInformationFile(FileHandleSource, &IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(Status)) { DPRINT1("NtQueryInformationFile failed: %x\n", Status); goto closesrc; } Status = NtCreateSection(&SourceFileSection, SECTION_MAP_READ, NULL, NULL, PAGE_READONLY, SEC_COMMIT, FileHandleSource); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName); goto closesrc; } Status = NtMapViewOfSection(SourceFileSection, NtCurrentProcess(), &SourceFileMap, 0, 0, NULL, &SourceSectionSize, ViewUnmap, 0, PAGE_READONLY ); if (!NT_SUCCESS(Status)) { DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName); goto closesrcsec; } RtlInitUnicodeString(&FileName, DestinationFileName); InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateFile(&FileHandleDest, GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_NO_INTERMEDIATE_BUFFERING | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateFile failed: %x\n", Status); goto unmapsrcsec; } RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart); IoStatusBlock.Status = 0; ByteOffset.QuadPart = 0; Status = NtWriteFile(FileHandleDest, NULL, NULL, NULL, &IoStatusBlock, SourceFileMap, RegionSize, &ByteOffset, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", Status, IoStatusBlock.Status, &IoStatusBlock, SourceFileMap, RegionSize); goto closedest; } /* Copy file date/time from source file */ Status = NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetInformationFile failed: %x\n", Status); goto closedest; } /* shorten the file back to it's real size after completing the write */ Status = NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileStandard.EndOfFile, sizeof(FILE_END_OF_FILE_INFORMATION), FileEndOfFileInformation); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetInformationFile failed: %x\n", Status); } closedest: NtClose(FileHandleDest); unmapsrcsec: NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap); closesrcsec: NtClose(SourceFileSection); closesrc: NtClose(FileHandleSource); done: return Status; }
/* * FUNCTION: Opens a cabinet file * RETURNS: * Status of operation */ ULONG CabinetOpen(VOID) { PUCHAR Buffer; UNICODE_STRING ustring; ANSI_STRING astring; if (!FileOpen) { OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING FileName; NTSTATUS NtStatus; ULONG Size; RtlInitUnicodeString(&FileName, CabinetName); InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); NtStatus = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(NtStatus)) { DPRINT("Cannot open file (%S) (%x)\n", CabinetName, NtStatus); return CAB_STATUS_CANNOT_OPEN; } FileOpen = TRUE; NtStatus = NtCreateSection(&FileSectionHandle, SECTION_ALL_ACCESS, 0, 0, PAGE_READONLY, SEC_COMMIT, FileHandle); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateSection failed: %x\n", NtStatus); return CAB_STATUS_NOMEMORY; } FileBuffer = 0; FileSize = 0; NtStatus = NtMapViewOfSection(FileSectionHandle, NtCurrentProcess(), (PVOID *)&FileBuffer, 0, 0, 0, &FileSize, ViewUnmap, 0, PAGE_READONLY); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtMapViewOfSection failed: %x\n", NtStatus); return CAB_STATUS_NOMEMORY; } DPRINT("Cabinet file %S opened and mapped to %x\n", CabinetName, FileBuffer); PCABHeader = (PCFHEADER) FileBuffer; /* Check header */ if (FileSize <= sizeof(CFHEADER) || PCABHeader->Signature != CAB_SIGNATURE || PCABHeader->Version != CAB_VERSION || PCABHeader->FolderCount == 0 || PCABHeader->FileCount == 0 || PCABHeader->FileTableOffset < sizeof(CFHEADER)) { CloseCabinet(); DPRINT("File has invalid header\n"); return CAB_STATUS_INVALID_CAB; } Size = 0; Buffer = (PUCHAR)(PCABHeader + 1); /* Read/skip any reserved bytes */ if (PCABHeader->Flags & CAB_FLAG_RESERVE) { CabinetReserved = *(PUSHORT)Buffer; Buffer += 2; FolderReserved = *Buffer; Buffer++; DataReserved = *Buffer; Buffer++; if (CabinetReserved > 0) { CabinetReservedArea = Buffer; Buffer += CabinetReserved; } } if (PCABHeader->Flags & CAB_FLAG_HASPREV) { /* The previous cabinet file is in the same directory as the current */ wcscpy(CabinetPrev, CabinetName); RemoveFileName(CabinetPrev); CabinetNormalizePath(CabinetPrev, 256); RtlInitAnsiString(&astring, (LPSTR)Buffer); ustring.Length = wcslen(CabinetPrev); ustring.Buffer = CabinetPrev + ustring.Length; ustring.MaximumLength = sizeof(CabinetPrev) - ustring.Length; RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); Buffer += astring.Length + 1; /* Read label of prev disk */ RtlInitAnsiString(&astring, (LPSTR)Buffer); ustring.Length = 0; ustring.Buffer = DiskPrev; ustring.MaximumLength = sizeof(DiskPrev); RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); Buffer += astring.Length + 1; } else { wcscpy(CabinetPrev, L""); wcscpy(DiskPrev, L""); } if (PCABHeader->Flags & CAB_FLAG_HASNEXT) { /* The next cabinet file is in the same directory as the previous */ wcscpy(CabinetNext, CabinetName); RemoveFileName(CabinetNext); CabinetNormalizePath(CabinetNext, 256); RtlInitAnsiString(&astring, (LPSTR)Buffer); ustring.Length = wcslen(CabinetNext); ustring.Buffer = CabinetNext + ustring.Length; ustring.MaximumLength = sizeof(CabinetNext) - ustring.Length; RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); Buffer += astring.Length + 1; /* Read label of next disk */ RtlInitAnsiString(&astring, (LPSTR)Buffer); ustring.Length = 0; ustring.Buffer = DiskNext; ustring.MaximumLength = sizeof(DiskNext); RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); Buffer += astring.Length + 1; } else { wcscpy(CabinetNext, L""); wcscpy(DiskNext, L""); } CabinetFolders = (PCFFOLDER)Buffer; } DPRINT("CabinetOpen returning SUCCESS\n"); return CAB_STATUS_SUCCESS; }
/* * Function for dealing with the undocumented message and structure used by * Windows' console.dll for setting console info. * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf * for more information. */ VOID GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData, HANDLE hClientSection) { NTSTATUS Status = STATUS_SUCCESS; PCONSRV_CONSOLE Console = GuiData->Console; PCONSOLE_PROCESS_DATA ProcessData; HANDLE hSection = NULL; ULONG ViewSize = 0; PCONSOLE_STATE_INFO pConInfo = NULL; if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return; /* Get the console leader process, our client */ ProcessData = ConSrvGetConsoleLeaderProcess(Console); /* Duplicate the section handle for ourselves */ Status = NtDuplicateObject(ProcessData->Process->ProcessHandle, hClientSection, NtCurrentProcess(), &hSection, 0, 0, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(Status)) { DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status); goto Quit; } /* Get a view of the shared section */ Status = NtMapViewOfSection(hSection, NtCurrentProcess(), (PVOID*)&pConInfo, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status); goto Quit; } _SEH2_TRY { /* Check that the section is well-sized */ if ( (ViewSize < sizeof(CONSOLE_STATE_INFO)) || (pConInfo->cbSize < sizeof(CONSOLE_STATE_INFO)) ) { DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n"); Status = STATUS_INVALID_VIEW_SIZE; _SEH2_YIELD(goto Quit); } // TODO: Check that GuiData->hWindow == pConInfo->hWnd /* Retrieve terminal informations */ /* Console information */ #if 0 // FIXME: Things not set ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize; ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers; ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup; ConInfo.CodePage = pConInfo->CodePage; #endif /* * Apply the settings */ /* Set the console informations */ ConSrvApplyUserSettings(Console, pConInfo); /* Set the terminal informations */ /* Change the font */ InitFonts(GuiData, pConInfo->FaceName, pConInfo->FontFamily, pConInfo->FontSize, pConInfo->FontWeight); // HACK, needed because changing font may change the size of the window /**/TermResizeTerminal(Console);/**/ /* Move the window to the user's values */ GuiData->GuiInfo.AutoPosition = !!pConInfo->AutoPosition; GuiData->GuiInfo.WindowOrigin = pConInfo->WindowPosition; GuiConsoleMoveWindow(GuiData); InvalidateRect(GuiData->hWindow, NULL, TRUE); /* * Apply full-screen mode. */ if (!!pConInfo->FullScreen != GuiData->GuiInfo.FullScreen) { SwitchFullScreen(GuiData, !!pConInfo->FullScreen); } /* * The settings are saved in the registry by console.dll itself, if needed. */ // if (SaveSettings) // { // GuiConsoleWriteUserSettings(GuiInfo); // } Status = STATUS_SUCCESS; }
NTSTATUS GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, IN OUT PCONSOLE Console, IN PGRAPHICS_BUFFER_INFO GraphicsInfo) { NTSTATUS Status = STATUS_SUCCESS; PGRAPHICS_SCREEN_BUFFER NewBuffer = NULL; LARGE_INTEGER SectionSize; ULONG ViewSize = 0; HANDLE ProcessHandle; if (Buffer == NULL || Console == NULL || GraphicsInfo == NULL) return STATUS_INVALID_PARAMETER; *Buffer = NULL; Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer, Console, sizeof(GRAPHICS_SCREEN_BUFFER)); if (!NT_SUCCESS(Status)) return Status; NewBuffer->Header.Type = GRAPHICS_BUFFER; NewBuffer->Vtbl = &GraphicsVtbl; /* * Remember the handle to the process so that we can close or unmap * correctly the allocated resources when the client releases the * screen buffer. */ ProcessHandle = CsrGetClientThread()->Process->ProcessHandle; NewBuffer->ClientProcess = ProcessHandle; /* Get infos from the graphics buffer information structure */ NewBuffer->BitMapInfoLength = GraphicsInfo->Info.dwBitMapInfoLength; NewBuffer->BitMapInfo = ConsoleAllocHeap(HEAP_ZERO_MEMORY, NewBuffer->BitMapInfoLength); if (NewBuffer->BitMapInfo == NULL) { CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer); return STATUS_INSUFFICIENT_RESOURCES; } /* Adjust the bitmap height if needed (bottom-top vs. top-bottom). Use always bottom-up. */ if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight > 0) GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight = -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight; /* We do not use anything else than uncompressed bitmaps */ if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression != BI_RGB) { DPRINT1("biCompression == %d != BI_RGB, correct that!\n", GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression); GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression = BI_RGB; } RtlCopyMemory(NewBuffer->BitMapInfo, GraphicsInfo->Info.lpBitMapInfo, GraphicsInfo->Info.dwBitMapInfoLength); NewBuffer->BitMapUsage = GraphicsInfo->Info.dwUsage; /* Set the screen buffer size. Fight against overflows. */ if ( GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth <= 0xFFFF && -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight <= 0xFFFF ) { /* Be careful about the sign of biHeight */ NewBuffer->ScreenBufferSize.X = (SHORT)GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth ; NewBuffer->ScreenBufferSize.Y = (SHORT)-GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight; NewBuffer->OldViewSize = NewBuffer->ViewSize = NewBuffer->OldScreenBufferSize = NewBuffer->ScreenBufferSize; } else { Status = STATUS_INSUFFICIENT_RESOURCES; ConsoleFreeHeap(NewBuffer->BitMapInfo); CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer); goto Quit; } /* * Create a mutex to synchronize bitmap memory access * between ourselves and the client. */ Status = NtCreateMutant(&NewBuffer->Mutex, MUTANT_ALL_ACCESS, NULL, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateMutant() failed: %lu\n", Status); ConsoleFreeHeap(NewBuffer->BitMapInfo); CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer); goto Quit; } /* * Duplicate the Mutex for the client. We must keep a trace of it * so that we can close it when the client releases the screen buffer. */ Status = NtDuplicateObject(NtCurrentProcess(), NewBuffer->Mutex, ProcessHandle, &NewBuffer->ClientMutex, 0, 0, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(Status)) { DPRINT1("NtDuplicateObject() failed: %lu\n", Status); NtClose(NewBuffer->Mutex); ConsoleFreeHeap(NewBuffer->BitMapInfo); CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer); goto Quit; } /* * Create a memory section for the bitmap area, to share with the client. */ SectionSize.QuadPart = NewBuffer->BitMapInfo->bmiHeader.biSizeImage; Status = NtCreateSection(&NewBuffer->hSection, SECTION_ALL_ACCESS, NULL, &SectionSize, PAGE_READWRITE, SEC_COMMIT, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status); NtClose(NewBuffer->ClientMutex); NtClose(NewBuffer->Mutex); ConsoleFreeHeap(NewBuffer->BitMapInfo); CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer); goto Quit; } /* * Create a view for our needs. */ ViewSize = 0; NewBuffer->BitMap = NULL; Status = NtMapViewOfSection(NewBuffer->hSection, NtCurrentProcess(), (PVOID*)&NewBuffer->BitMap, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status); NtClose(NewBuffer->hSection); NtClose(NewBuffer->ClientMutex); NtClose(NewBuffer->Mutex); ConsoleFreeHeap(NewBuffer->BitMapInfo); CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer); goto Quit; } /* * Create a view for the client. We must keep a trace of it so that * we can unmap it when the client releases the screen buffer. */ ViewSize = 0; NewBuffer->ClientBitMap = NULL; Status = NtMapViewOfSection(NewBuffer->hSection, ProcessHandle, (PVOID*)&NewBuffer->ClientBitMap, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status); NtUnmapViewOfSection(NtCurrentProcess(), NewBuffer->BitMap); NtClose(NewBuffer->hSection); NtClose(NewBuffer->ClientMutex); NtClose(NewBuffer->Mutex); ConsoleFreeHeap(NewBuffer->BitMapInfo); CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer); goto Quit; } NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0; NewBuffer->VirtualY = 0; NewBuffer->CursorBlinkOn = FALSE; NewBuffer->ForceCursorOff = TRUE; NewBuffer->CursorInfo.bVisible = FALSE; NewBuffer->CursorInfo.dwSize = 0; NewBuffer->CursorPosition.X = NewBuffer->CursorPosition.Y = 0; NewBuffer->Mode = 0; *Buffer = (PCONSOLE_SCREEN_BUFFER)NewBuffer; Status = STATUS_SUCCESS; Quit: return Status; }
VOID PropertiesUpdate( IN PCONSOLE_INFORMATION Console, IN HANDLE hClientSection ) /*++ Updates the console state from information sent by the properties dialog box. --*/ { HANDLE hSection; ULONG ulViewSize; NTSTATUS Status; PCONSOLE_STATE_INFO pStateInfo; PCONSOLE_PROCESS_HANDLE ProcessHandleRecord; PSCREEN_INFORMATION ScreenInfo; ULONG FontIndex; WINDOWPLACEMENT wp; COORD NewSize; /* * Map the shared memory block handle into our address space. */ ProcessHandleRecord = CONTAINING_RECORD(Console->ProcessHandleList.Blink, CONSOLE_PROCESS_HANDLE, ListLink); Status = NtDuplicateObject(ProcessHandleRecord->ProcessHandle, hClientSection, NtCurrentProcess(), &hSection, 0, 0, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(Status)) { KdPrint(("CONSRV: error %x mapping client handle\n", Status)); return; } /* * Get a pointer to the shared memory block. */ pStateInfo = NULL; ulViewSize = 0; Status = NtMapViewOfSection(hSection, NtCurrentProcess(), &pStateInfo, 0, 0, NULL, &ulViewSize, ViewUnmap, 0, PAGE_READONLY); if (!NT_SUCCESS(Status)) { KdPrint(("CONSRV: error %x mapping view of file\n", Status)); NtClose(hSection); return; } /* * Verify the size of the shared memory block. */ if (ulViewSize < sizeof(CONSOLE_STATE_INFO)) { KdPrint(("CONSRV: sizeof(hSection) < sizeof(CONSOLE_STATE_INFO)\n")); NtUnmapViewOfSection(NtCurrentProcess(), pStateInfo); NtClose(hSection); return; } /* * Update the console state from the supplied values. */ ScreenInfo = Console->CurrentScreenBuffer; if (!(Console->Flags & CONSOLE_VDM_REGISTERED) && (pStateInfo->ScreenBufferSize.X != ScreenInfo->ScreenBufferSize.X || pStateInfo->ScreenBufferSize.Y != ScreenInfo->ScreenBufferSize.Y)) { ResizeScreenBuffer(ScreenInfo, pStateInfo->ScreenBufferSize, TRUE); } FontIndex = FindCreateFont(pStateInfo->FontFamily, pStateInfo->FaceName, pStateInfo->FontSize, pStateInfo->FontWeight); SetScreenBufferFont(ScreenInfo, FontIndex); SetCursorInformation(ScreenInfo, pStateInfo->CursorSize, ScreenInfo->BufferInfo.TextInfo.CursorVisible); NewSize.X = min(pStateInfo->WindowSize.X, ScreenInfo->MaximumWindowSize.X); NewSize.Y = min(pStateInfo->WindowSize.Y, ScreenInfo->MaximumWindowSize.Y); if (NewSize.X != CONSOLE_WINDOW_SIZE_X(ScreenInfo) || NewSize.Y != CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) { wp.length = sizeof(wp); GetWindowPlacement(Console->hWnd, &wp); wp.rcNormalPosition.right += (NewSize.X - CONSOLE_WINDOW_SIZE_X(ScreenInfo)) * SCR_FONTSIZE(ScreenInfo).X; wp.rcNormalPosition.bottom += (NewSize.Y - CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) * SCR_FONTSIZE(ScreenInfo).Y; SetWindowPlacement(Console->hWnd, &wp); } #ifdef i386 if (FullScreenInitialized) { if (pStateInfo->FullScreen == FALSE) { if (Console->FullScreenFlags & CONSOLE_FULLSCREEN) { ConvertToWindowed(Console); ASSERT(!(Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE)); Console->FullScreenFlags = 0; ChangeDispSettings(Console, Console->hWnd, 0); } } else { if (Console->FullScreenFlags == 0) { ConvertToFullScreen(Console); Console->FullScreenFlags |= CONSOLE_FULLSCREEN; ChangeDispSettings(Console, Console->hWnd, CDS_FULLSCREEN); } } } #endif if (pStateInfo->QuickEdit) { Console->Flags |= CONSOLE_QUICK_EDIT_MODE; } else { Console->Flags &= ~CONSOLE_QUICK_EDIT_MODE; } if (pStateInfo->AutoPosition) { Console->Flags |= CONSOLE_AUTO_POSITION; } else { Console->Flags &= ~CONSOLE_AUTO_POSITION; SetWindowPos(Console->hWnd, NULL, pStateInfo->WindowPosX, pStateInfo->WindowPosY, 0, 0, SWP_NOZORDER | SWP_NOSIZE); } if (Console->InsertMode != pStateInfo->InsertMode) { SetCursorMode(ScreenInfo, FALSE); Console->InsertMode = pStateInfo->InsertMode; } RtlCopyMemory(Console->ColorTable, pStateInfo->ColorTable, sizeof(Console->ColorTable)); SetScreenColors(ScreenInfo, pStateInfo->ScreenAttributes, pStateInfo->PopupAttributes, TRUE); Console->CommandHistorySize = pStateInfo->HistoryBufferSize; Console->MaxCommandHistories = pStateInfo->NumberOfHistoryBuffers; if (pStateInfo->HistoryNoDup) { Console->Flags |= CONSOLE_HISTORY_NODUP; } else { Console->Flags &= ~CONSOLE_HISTORY_NODUP; } NtUnmapViewOfSection(NtCurrentProcess(), pStateInfo); NtClose(hSection); return; }
VOID PropertiesDlgShow( IN PCONSOLE_INFORMATION Console ) /*++ Displays the properties dialog and updates the window state, if necessary. --*/ { HANDLE hSection = NULL; HANDLE hClientSection = NULL; HANDLE hThread; ULONG ulViewSize; LARGE_INTEGER li; NTSTATUS Status; PCONSOLE_STATE_INFO pStateInfo; PCONSOLE_PROCESS_HANDLE ProcessHandleRecord; PSCREEN_INFORMATION ScreenInfo; LPTHREAD_START_ROUTINE MyPropRoutine; /* * Create a shared memory block. */ li.QuadPart = sizeof(CONSOLE_STATE_INFO) + Console->OriginalTitleLength; Status = NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &li, PAGE_READWRITE, SEC_COMMIT, NULL); if (!NT_SUCCESS(Status)) { KdPrint(("CONSRV: error %x creating file mapping\n", Status)); return; } /* * Get a pointer to the shared memory block. */ pStateInfo = NULL; ulViewSize = 0; Status = NtMapViewOfSection(hSection, NtCurrentProcess(), &pStateInfo, 0, 0, NULL, &ulViewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { KdPrint(("CONSRV: error %x mapping view of file\n", Status)); NtClose(hSection); return; } /* * Fill in the shared memory block with the current values. */ ScreenInfo = Console->CurrentScreenBuffer; pStateInfo->Length = li.LowPart; pStateInfo->ScreenBufferSize = ScreenInfo->ScreenBufferSize; pStateInfo->WindowSize.X = CONSOLE_WINDOW_SIZE_X(ScreenInfo); pStateInfo->WindowSize.Y = CONSOLE_WINDOW_SIZE_Y(ScreenInfo); pStateInfo->WindowPosX = Console->WindowRect.left; pStateInfo->WindowPosY = Console->WindowRect.top; if (ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) { pStateInfo->FontSize = SCR_FONTSIZE(ScreenInfo); pStateInfo->FontFamily = SCR_FAMILY(ScreenInfo); pStateInfo->FontWeight = SCR_FONTWEIGHT(ScreenInfo); wcscpy(pStateInfo->FaceName, SCR_FACENAME(ScreenInfo)); pStateInfo->CursorSize = ScreenInfo->BufferInfo.TextInfo.CursorSize; } pStateInfo->FullScreen = Console->FullScreenFlags & CONSOLE_FULLSCREEN; pStateInfo->QuickEdit = Console->Flags & CONSOLE_QUICK_EDIT_MODE; pStateInfo->AutoPosition = Console->Flags & CONSOLE_AUTO_POSITION; pStateInfo->InsertMode = Console->InsertMode; pStateInfo->ScreenAttributes = ScreenInfo->Attributes; pStateInfo->PopupAttributes = ScreenInfo->PopupAttributes; pStateInfo->HistoryBufferSize = Console->CommandHistorySize; pStateInfo->NumberOfHistoryBuffers = Console->MaxCommandHistories; pStateInfo->HistoryNoDup = Console->Flags & CONSOLE_HISTORY_NODUP; RtlCopyMemory(pStateInfo->ColorTable, Console->ColorTable, sizeof(Console->ColorTable)); pStateInfo->hWnd = Console->hWnd; wcscpy(pStateInfo->ConsoleTitle, Console->OriginalTitle); NtUnmapViewOfSection(NtCurrentProcess(), pStateInfo); /* * Map the shared memory block handle into the client side process's * address space. */ ProcessHandleRecord = CONTAINING_RECORD(Console->ProcessHandleList.Blink, CONSOLE_PROCESS_HANDLE, ListLink); Status = NtDuplicateObject(NtCurrentProcess(), hSection, ProcessHandleRecord->ProcessHandle, &hClientSection, 0, 0, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(Status)) { KdPrint(("CONSRV: error %x mapping handle to client\n", Status)); NtClose(hSection); return; } /* * Get a pointer to the client-side properties routine. */ if (ProcessHandleRecord->PropRoutine) { MyPropRoutine = ProcessHandleRecord->PropRoutine; } else { MyPropRoutine = PropRoutine; } /* * Call back into the client process to spawn the properties dialog. */ UnlockConsole(Console); hThread = InternalCreateCallbackThread(ProcessHandleRecord->ProcessHandle, (DWORD)MyPropRoutine, (DWORD)hClientSection); if (!hThread) { KdPrint(("CONSRV: CreateRemoteThread failed %d\n", GetLastError())); } LockConsole(Console); /* * Close any open handles and free allocated memory. */ if (hThread) NtClose(hThread); if (hSection) NtClose(hSection); return; }
/* * Function for dealing with the undocumented message and structure used by * Windows' console.dll for setting console info. * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf * for more information. */ VOID GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData, HANDLE hClientSection) { NTSTATUS Status = STATUS_SUCCESS; PCONSRV_CONSOLE Console = GuiData->Console; PCONSOLE_PROCESS_DATA ProcessData; HANDLE hSection = NULL; ULONG ViewSize = 0; PCONSOLE_STATE_INFO pConInfo = NULL; CONSOLE_INFO ConInfo; GUI_CONSOLE_INFO GuiInfo; #if 0 SIZE_T Length; #endif if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return; /* Get the console leader process, our client */ ProcessData = ConSrvGetConsoleLeaderProcess(Console); /* Duplicate the section handle for ourselves */ Status = NtDuplicateObject(ProcessData->Process->ProcessHandle, hClientSection, NtCurrentProcess(), &hSection, 0, 0, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(Status)) { DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status); goto Quit; } /* Get a view of the shared section */ Status = NtMapViewOfSection(hSection, NtCurrentProcess(), (PVOID*)&pConInfo, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status); goto Quit; } _SEH2_TRY { /* Check that the section is well-sized */ if ( (ViewSize < sizeof(CONSOLE_STATE_INFO)) || (pConInfo->cbSize != sizeof(CONSOLE_STATE_INFO)) ) { DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n"); Status = STATUS_INVALID_VIEW_SIZE; _SEH2_YIELD(goto Quit); } // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow /* Retrieve terminal informations */ // Console information ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize; ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers; ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup; ConInfo.QuickEdit = !!pConInfo->QuickEdit; ConInfo.InsertMode = !!pConInfo->InsertMode; ConInfo.ScreenBufferSize = pConInfo->ScreenBufferSize; ConInfo.ConsoleSize = pConInfo->WindowSize; ConInfo.CursorSize = pConInfo->CursorSize; ConInfo.ScreenAttrib = pConInfo->ScreenColors; ConInfo.PopupAttrib = pConInfo->PopupColors; memcpy(&ConInfo.Colors, pConInfo->ColorTable, sizeof(ConInfo.Colors)); ConInfo.CodePage = pConInfo->CodePage; /**ConInfo.ConsoleTitle[MAX_PATH + 1] = pConInfo->ConsoleTitle; // FIXME: memcpy**/ #if 0 /* Title of the console, original one corresponding to the one set by the console leader */ Length = min(sizeof(pConInfo->ConsoleTitle) / sizeof(pConInfo->ConsoleTitle[0]) - 1, Console->OriginalTitle.Length / sizeof(WCHAR)); wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length); #endif // BOOLEAN ConInfo.CursorBlinkOn = pConInfo-> // BOOLEAN ConInfo.ForceCursorOff = pConInfo-> // Terminal information wcsncpy(GuiInfo.FaceName, pConInfo->FaceName, LF_FACESIZE); GuiInfo.FaceName[LF_FACESIZE - 1] = UNICODE_NULL; GuiInfo.FontFamily = pConInfo->FontFamily; GuiInfo.FontSize = pConInfo->FontSize; GuiInfo.FontWeight = pConInfo->FontWeight; GuiInfo.FullScreen = !!pConInfo->FullScreen; GuiInfo.AutoPosition = !!pConInfo->AutoPosition; GuiInfo.WindowOrigin = pConInfo->WindowPosition; // WORD GuiInfo.ShowWindow = pConInfo-> /* * If we don't set the default parameters, * apply them, otherwise just save them. */ #if 0 if (pConInfo->ShowDefaultParams == FALSE) #endif { /* Set the console informations */ ConSrvApplyUserSettings(Console, &ConInfo); /* Set the terminal informations */ // memcpy(&GuiData->GuiInfo, &GuiInfo, sizeof(GUI_CONSOLE_INFO)); /* Change the font */ InitFonts(GuiData, GuiInfo.FaceName, GuiInfo.FontFamily, GuiInfo.FontSize, GuiInfo.FontWeight); // HACK, needed because changing font may change the size of the window /**/TermResizeTerminal(Console);/**/ /* Move the window to the user's values */ GuiData->GuiInfo.AutoPosition = GuiInfo.AutoPosition; GuiData->GuiInfo.WindowOrigin = GuiInfo.WindowOrigin; GuiConsoleMoveWindow(GuiData); InvalidateRect(GuiData->hWindow, NULL, TRUE); /* * Apply full-screen mode. */ if (GuiInfo.FullScreen != GuiData->GuiInfo.FullScreen) { SwitchFullScreen(GuiData, GuiInfo.FullScreen); } } #if 0 /* * Save settings if needed */ // FIXME: Do it in the console properties applet ?? if (SaveSettings) { DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess); ConSrvWriteUserSettings(&ConInfo, ProcessId); GuiConsoleWriteUserSettings(&GuiInfo, ConInfo.ConsoleTitle, ProcessId); } #endif Status = STATUS_SUCCESS; }
LPVOID APIENTRY MapViewOfFileEx( HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, DWORD dwNumberOfBytesToMap, LPVOID lpBaseAddress ) /*++ Routine Description: A view of a file may be mapped into the address space of the calling process using MapViewOfFileEx. Mapping a file object makes the specified portion of the file visible in the address space of the calling process. The return address is a pointer to memory that when addressed causes data within the file to be accessed. This API allows the caller to supply the system with a suggested mapping address. The system will round this address down to the nearest 64k boundry and attempt to map the file at thet address. If there is not enough address space at that address, this call will fail. Mapping a view of a file has some simple coherency rules: - Multiple views on a file are coherent if they are derived from the same file mapping object. If a process opens a file, creates a mapping object, duplicates the object to another process... If both processes map a view of the file, they will both see a coherent view of the file's data... they will effectively be viewing shared memory backed by the file. - If multiple mapping objects exist for the same file, then views derived from the different mapping objects are not garunteed to be coherent. - A mapped view on a file is not garunteed to be coherent with a file being accessed via ReadFile or WriteFile. Arguments: hFileMappingObject - Supplies an open handle to a file mapping object that is to be mapped into the callers address space. dwDesiredAccess - Specifies the access that is requested to the file mapping object. This determines the page protection of the pages mapped by the file. dwDesiredAccess Values: FILE_MAP_WRITE - Read/write access is desired. The mapping object must have been created with PAGE_READWRITE protection. The hFileMappingObject must have been created with FILE_MAP_WRITE access. A read/write view of the file will be mapped. FILE_MAP_READ - Read access is desired. The mapping object must have been created with PAGE_READWRITE or PAGE_READ protection. The hFileMappingObject must have been created with FILE_MAP_READ access. A read only view of the file will be mapped. dwFileOffsetHigh - Supplies the high order 32-bits of the file offset where mapping is to begin. dwFileOffsetLow - Supplies the low order 32-bits of the file offset where mapping is to begin. The combination of the high and low offsets must specify a 64Kb aligned offset within the file. It is an error if this is not the case. dwNumberOfBytesToMap - Supplies the number of bytes of the file to map. A value of zero specifies that the entire file is to be mapped. lpBaseAddress - Supplies the base address of where in the processes address space the mapping is to begin at. The address is rounded down to the nearest 64k boundry by the system. A value of NULL for this parameter operates exactly the same as MapViewOfFile... The system picks the mapping base address without any hint from the caller. Return Value: NON-NULL - Returns the address of where the file is mapped. NULL - The operation failed. Extended error status is available using GetLastError. --*/ { NTSTATUS Status; LARGE_INTEGER SectionOffset; ULONG ViewSize; PVOID ViewBase; ULONG Protect; SectionOffset.LowPart = dwFileOffsetLow; SectionOffset.HighPart = dwFileOffsetHigh; ViewSize = dwNumberOfBytesToMap; ViewBase = lpBaseAddress; if ( dwDesiredAccess == FILE_MAP_COPY ) { Protect = PAGE_WRITECOPY; } else if ( dwDesiredAccess & FILE_MAP_WRITE ) { Protect = PAGE_READWRITE; } else if ( dwDesiredAccess & FILE_MAP_READ ) { Protect = PAGE_READONLY; } else { Protect = PAGE_NOACCESS; } Status = NtMapViewOfSection( hFileMappingObject, NtCurrentProcess(), &ViewBase, 0L, 0L, &SectionOffset, &ViewSize, ViewShare, 0L, Protect ); if ( !NT_SUCCESS(Status) ) { BaseSetLastNTError(Status); return NULL; } return ViewBase; }
NTSTATUS ApfCreateDataSection(PAPFCONTROL *ApfDataSectionPointer) { NTSTATUS Status; STRING ApfDataSectionName; UNICODE_STRING ApfDataSectionUnicodeName; OBJECT_ATTRIBUTES ObjectAttributes; LARGE_INTEGER AllocationSize; ULONG ViewSize; PAPFCONTROL DataSectionPointer; // // Initialize object attributes // RtlInitString(&ApfDataSectionName, DATA_SEC_NAME); Status = RtlAnsiStringToUnicodeString( &ApfDataSectionUnicodeName, &ApfDataSectionName, TRUE); if (NT_SUCCESS(Status)) { InitializeObjectAttributes( &ObjectAttributes, &ApfDataSectionUnicodeName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, &SecDescriptor); } #ifdef ERRORDBG else { KdPrint (("WAP: RtlAnsiStringToUnicodeString() failed in " "ApfCreateDataSection, %lx\n", Status)); } #endif AllocationSize.HighPart = 0; // Need a slot to account for calibration data // AllocationSize.LowPart = (API_COUNT + 1) * sizeof(APFDATA); // Create a read-write section // Status = NtCreateSection(&ApfDataSectionHandle, SECTION_MAP_READ | SECTION_MAP_WRITE, &ObjectAttributes, &AllocationSize, PAGE_READWRITE, SEC_COMMIT, NULL); if (NT_SUCCESS(Status)) { ViewSize = AllocationSize.LowPart; DataSectionPointer = NULL; // Map the section // Status = NtMapViewOfSection(ApfDataSectionHandle, MyProcess, (PVOID *)&DataSectionPointer, 0, AllocationSize.LowPart, NULL, &ViewSize, ViewUnmap, 0L, PAGE_READWRITE); #ifdef ERRORDBG if (!NT_SUCCESS(Status)) { KdPrint (("WAP: NtMapViewOfSection() failed in ApfCreateDataSection," " %lx\n", Status)); } #endif *ApfDataSectionPointer = DataSectionPointer; } #ifdef ERRORDBG else { KdPrint (("WAP: NtCreateSection() failed in ApfCreateDataSection " "%lx\n", Status)); } #endif return(Status); } /* ApfCreateDataSection () */
static NTSTATUS TH32CreateSnapshotSectionInitialize(DWORD dwFlags, DWORD th32ProcessID, PRTL_DEBUG_INFORMATION HeapDebug, PRTL_DEBUG_INFORMATION ModuleDebug, PVOID ProcThrdInfo, HANDLE *SectionHandle) { PSYSTEM_PROCESS_INFORMATION ProcessInfo; LPHEAPLIST32 HeapListEntry; LPMODULEENTRY32W ModuleListEntry; LPPROCESSENTRY32W ProcessListEntry; LPTHREADENTRY32 ThreadListEntry; OBJECT_ATTRIBUTES ObjectAttributes; LARGE_INTEGER SSize, SOffset; HANDLE hSection; PTH32SNAPSHOT Snapshot; ULONG_PTR DataOffset; SIZE_T ViewSize; ULONG i, nProcesses = 0, nThreads = 0, nHeaps = 0, nModules = 0; ULONG RequiredSnapshotSize = sizeof(TH32SNAPSHOT); PRTL_PROCESS_HEAPS hi = NULL; PRTL_PROCESS_MODULES mi = NULL; NTSTATUS Status = STATUS_SUCCESS; /* * Determine the required size for the heap snapshot */ if(dwFlags & TH32CS_SNAPHEAPLIST) { hi = (PRTL_PROCESS_HEAPS)HeapDebug->Heaps; nHeaps = hi->NumberOfHeaps; RequiredSnapshotSize += nHeaps * sizeof(HEAPLIST32); } /* * Determine the required size for the module snapshot */ if(dwFlags & TH32CS_SNAPMODULE) { mi = (PRTL_PROCESS_MODULES)ModuleDebug->Modules; nModules = mi->NumberOfModules; RequiredSnapshotSize += nModules * sizeof(MODULEENTRY32W); } /* * Determine the required size for the processes and threads snapshot */ if(dwFlags & (TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD)) { ULONG ProcOffset = 0; ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo; do { ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset); nProcesses++; nThreads += ProcessInfo->NumberOfThreads; ProcOffset = ProcessInfo->NextEntryOffset; } while(ProcOffset != 0); if(dwFlags & TH32CS_SNAPPROCESS) { RequiredSnapshotSize += nProcesses * sizeof(PROCESSENTRY32W); } if(dwFlags & TH32CS_SNAPTHREAD) { RequiredSnapshotSize += nThreads * sizeof(THREADENTRY32); } } /* * Create and map the section */ SSize.QuadPart = RequiredSnapshotSize; InitializeObjectAttributes(&ObjectAttributes, NULL, ((dwFlags & TH32CS_INHERIT) ? OBJ_INHERIT : 0), NULL, NULL); Status = NtCreateSection(&hSection, SECTION_ALL_ACCESS, &ObjectAttributes, &SSize, PAGE_READWRITE, SEC_COMMIT, NULL); if(!NT_SUCCESS(Status)) { return Status; } SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL; Status = NtMapViewOfSection(hSection, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(!NT_SUCCESS(Status)) { NtClose(hSection); return Status; } RtlZeroMemory(Snapshot, sizeof(TH32SNAPSHOT)); DataOffset = 0; /* * Initialize the section data and fill it with all the data we collected */ /* initialize the heap list */ if(dwFlags & TH32CS_SNAPHEAPLIST) { Snapshot->HeapListCount = nHeaps; Snapshot->HeapListOffset = DataOffset; HeapListEntry = (LPHEAPLIST32)OffsetToPtr(Snapshot, DataOffset); for(i = 0; i < nHeaps; i++) { HeapListEntry->dwSize = sizeof(HEAPLIST32); HeapListEntry->th32ProcessID = th32ProcessID; HeapListEntry->th32HeapID = (ULONG_PTR)hi->Heaps[i].BaseAddress; HeapListEntry->dwFlags = hi->Heaps[i].Flags; HeapListEntry++; } DataOffset += hi->NumberOfHeaps * sizeof(HEAPLIST32); } /* initialize the module list */ if(dwFlags & TH32CS_SNAPMODULE) { Snapshot->ModuleListCount = nModules; Snapshot->ModuleListOffset = DataOffset; ModuleListEntry = (LPMODULEENTRY32W)OffsetToPtr(Snapshot, DataOffset); for(i = 0; i < nModules; i++) { ModuleListEntry->dwSize = sizeof(MODULEENTRY32W); ModuleListEntry->th32ModuleID = 1; /* no longer used, always set to one! */ ModuleListEntry->th32ProcessID = th32ProcessID; ModuleListEntry->GlblcntUsage = mi->Modules[i].LoadCount; ModuleListEntry->ProccntUsage = mi->Modules[i].LoadCount; ModuleListEntry->modBaseAddr = (BYTE*)mi->Modules[i].ImageBase; ModuleListEntry->modBaseSize = mi->Modules[i].ImageSize; ModuleListEntry->hModule = (HMODULE)mi->Modules[i].ImageBase; MultiByteToWideChar(CP_ACP, 0, &mi->Modules[i].FullPathName[mi->Modules[i].OffsetToFileName], -1, ModuleListEntry->szModule, sizeof(ModuleListEntry->szModule) / sizeof(ModuleListEntry->szModule[0])); MultiByteToWideChar(CP_ACP, 0, mi->Modules[i].FullPathName, -1, ModuleListEntry->szExePath, sizeof(ModuleListEntry->szExePath) / sizeof(ModuleListEntry->szExePath[0])); ModuleListEntry++; } DataOffset += mi->NumberOfModules * sizeof(MODULEENTRY32W); } /* initialize the process list */ if(dwFlags & TH32CS_SNAPPROCESS) { ULONG ProcOffset = 0; Snapshot->ProcessListCount = nProcesses; Snapshot->ProcessListOffset = DataOffset; ProcessListEntry = (LPPROCESSENTRY32W)OffsetToPtr(Snapshot, DataOffset); ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo; do { ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset); ProcessListEntry->dwSize = sizeof(PROCESSENTRY32W); ProcessListEntry->cntUsage = 0; /* no longer used */ ProcessListEntry->th32ProcessID = (ULONG_PTR)ProcessInfo->UniqueProcessId; ProcessListEntry->th32DefaultHeapID = 0; /* no longer used */ ProcessListEntry->th32ModuleID = 0; /* no longer used */ ProcessListEntry->cntThreads = ProcessInfo->NumberOfThreads; ProcessListEntry->th32ParentProcessID = (ULONG_PTR)ProcessInfo->InheritedFromUniqueProcessId; ProcessListEntry->pcPriClassBase = ProcessInfo->BasePriority; ProcessListEntry->dwFlags = 0; /* no longer used */ if(ProcessInfo->ImageName.Buffer != NULL) { lstrcpynW(ProcessListEntry->szExeFile, ProcessInfo->ImageName.Buffer, min(ProcessInfo->ImageName.Length / sizeof(WCHAR), sizeof(ProcessListEntry->szExeFile) / sizeof(ProcessListEntry->szExeFile[0]))); } else { lstrcpyW(ProcessListEntry->szExeFile, L"[System Process]"); } ProcessListEntry++; ProcOffset = ProcessInfo->NextEntryOffset; } while(ProcOffset != 0); DataOffset += nProcesses * sizeof(PROCESSENTRY32W); } /* initialize the thread list */ if(dwFlags & TH32CS_SNAPTHREAD) { ULONG ProcOffset = 0; Snapshot->ThreadListCount = nThreads; Snapshot->ThreadListOffset = DataOffset; ThreadListEntry = (LPTHREADENTRY32)OffsetToPtr(Snapshot, DataOffset); ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo; do { PSYSTEM_THREAD_INFORMATION ThreadInfo; ULONG n; ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset); ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1); for(n = 0; n < ProcessInfo->NumberOfThreads; n++) { ThreadListEntry->dwSize = sizeof(THREADENTRY32); ThreadListEntry->cntUsage = 0; /* no longer used */ ThreadListEntry->th32ThreadID = (ULONG_PTR)ThreadInfo->ClientId.UniqueThread; ThreadListEntry->th32OwnerProcessID = (ULONG_PTR)ThreadInfo->ClientId.UniqueProcess; ThreadListEntry->tpBasePri = ThreadInfo->BasePriority; ThreadListEntry->tpDeltaPri = 0; /* no longer used */ ThreadListEntry->dwFlags = 0; /* no longer used */ ThreadInfo++; ThreadListEntry++; } ProcOffset = ProcessInfo->NextEntryOffset; } while(ProcOffset != 0); } /* * We're done, unmap the view and return the section handle */ Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); if(NT_SUCCESS(Status)) { *SectionHandle = hSection; } else { NtClose(hSection); } return Status; }
static NTSTATUS BasepLoadLibraryAsDatafile(PWSTR Path, LPCWSTR Name, HMODULE *hModule) { WCHAR FilenameW[MAX_PATH]; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMapping; NTSTATUS Status; PVOID lpBaseAddress = NULL; SIZE_T ViewSize = 0; //PUNICODE_STRING OriginalName; //UNICODE_STRING dotDLL = RTL_CONSTANT_STRING(L".DLL"); /* Zero out handle value */ *hModule = 0; DPRINT("BasepLoadLibraryAsDatafile(%S %S %p)\n", Path, Name, hModule); /*Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE, Name, &dotDLL, RedirName, RedirName2, &OriginalName2, NULL, NULL, NULL);*/ /* Try to search for it */ if (!SearchPathW(Path, Name, L".DLL", sizeof(FilenameW) / sizeof(FilenameW[0]), FilenameW, NULL)) { /* Return last status value directly */ return NtCurrentTeb()->LastStatusValue; } /* Open this file we found */ hFile = CreateFileW(FilenameW, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0); /* If opening failed - return last status value */ if (hFile == INVALID_HANDLE_VALUE) return NtCurrentTeb()->LastStatusValue; /* Create file mapping */ hMapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL); /* Close the file handle */ CloseHandle(hFile); /* If creating file mapping failed - return last status value */ if (!hMapping) return NtCurrentTeb()->LastStatusValue; /* Map view of section */ Status = NtMapViewOfSection(hMapping, NtCurrentProcess(), &lpBaseAddress, 0, 0, 0, &ViewSize, ViewShare, 0, PAGE_READONLY); /* Close handle to the section */ CloseHandle(hMapping); /* If mapping view of section failed - return last status value */ if (!NT_SUCCESS(Status)) return NtCurrentTeb()->LastStatusValue; /* Make sure it's a valid PE file */ if (!RtlImageNtHeader(lpBaseAddress)) { /* Unmap the view and return failure status */ UnmapViewOfFile(lpBaseAddress); return STATUS_INVALID_IMAGE_FORMAT; } /* Set low bit of handle to indicate datafile module */ *hModule = (HMODULE)((ULONG_PTR)lpBaseAddress | 1); /* Load alternate resource module */ //LdrLoadAlternateResourceModule(*hModule, FilenameW); return STATUS_SUCCESS; }
NTSTATUS SrvValidateSlmStatus( IN HANDLE StatusFile, OUT PULONG FileOffsetOfInvalidData ) { NTSTATUS Status; IO_STATUS_BLOCK IoStatus; FILE_STANDARD_INFORMATION FileInformation; HANDLE Section; PVOID ViewBase; ULONG ViewSize; *FileOffsetOfInvalidData = -1; if ( !SrvDisallowSlmAccessEnabled ) { return STATUS_SUCCESS; } Status = NtQueryInformationFile( StatusFile, &IoStatus, (PVOID) &FileInformation, sizeof( FileInformation ), FileStandardInformation ); if (!NT_SUCCESS( Status )) { return( Status ); } Status = NtCreateSection( &Section, SECTION_ALL_ACCESS, NULL, NULL, PAGE_READONLY, SEC_COMMIT, StatusFile ); if (!NT_SUCCESS( Status )) { if (Status == STATUS_MAPPED_FILE_SIZE_ZERO) { return( STATUS_SUCCESS ); } return( Status ); } ViewBase = NULL; ViewSize = 0; Status = NtMapViewOfSection( Section, NtCurrentProcess(), &ViewBase, 0L, 0L, NULL, &ViewSize, ViewShare, 0L, PAGE_READONLY ); NtClose( Section ); if (!NT_SUCCESS( Status )) { if (Status == STATUS_MAPPED_FILE_SIZE_ZERO) { return( STATUS_SUCCESS ); } else { return( Status ); } } Status = SrvpValidateStatusFile( ViewBase, FileInformation.EndOfFile.LowPart, FileOffsetOfInvalidData ); (VOID)NtUnmapViewOfSection( NtCurrentProcess(), ViewBase ); return( Status ); }
/* * FUNCTION: Extracts a file from the cabinet * ARGUMENTS: * Search = Pointer to PCAB_SEARCH structure used to locate the file * RETURNS * Status of operation */ ULONG CabinetExtractFile(PCAB_SEARCH Search) { ULONG Size; // remaining file bytes to decompress ULONG CurrentOffset; // current uncompressed offset within the folder PUCHAR CurrentBuffer; // current pointer to compressed data in the block LONG RemainingBlock; // remaining comp data in the block HANDLE DestFile; HANDLE DestFileSection; PVOID DestFileBuffer; // mapped view of dest file PVOID CurrentDestBuffer; // pointer to the current position in the dest view PCFDATA CFData; // current data block ULONG Status; FILETIME FileTime; WCHAR DestName[MAX_PATH]; NTSTATUS NtStatus; UNICODE_STRING UnicodeString; ANSI_STRING AnsiString; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; FILE_BASIC_INFORMATION FileBasic; PCFFOLDER CurrentFolder; LARGE_INTEGER MaxDestFileSize; LONG InputLength, OutputLength; char Junk[512]; if (wcscmp(Search->Cabinet, CabinetName) != 0) { /* the file is not in the current cabinet */ DPRINT("File is not in this cabinet (%S != %S)\n", Search->Cabinet, CabinetName); return CAB_STATUS_NOFILE; } /* look up the folder that the file specifies */ if (Search->File->FolderIndex == 0xFFFD || Search->File->FolderIndex == 0xFFFF) { /* folder is continued from previous cabinet, that shouldn't happen here */ return CAB_STATUS_NOFILE; } else if (Search->File->FolderIndex == 0xFFFE) { /* folder is the last in this cabinet and continues into next */ CurrentFolder = &CabinetFolders[PCABHeader->FolderCount - 1]; } else { /* folder is completely contained within this cabinet */ CurrentFolder = &CabinetFolders[Search->File->FolderIndex]; } switch (CurrentFolder->CompressionType & CAB_COMP_MASK) { case CAB_COMP_NONE: CabinetSelectCodec(CAB_CODEC_RAW); break; case CAB_COMP_MSZIP: CabinetSelectCodec(CAB_CODEC_MSZIP); break; default: return CAB_STATUS_UNSUPPCOMP; } DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n", (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize); RtlInitAnsiString(&AnsiString, Search->File->FileName); wcscpy(DestName, DestPath); UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) * sizeof(WCHAR); UnicodeString.Buffer = DestName + wcslen(DestName); UnicodeString.Length = 0; RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); /* Create destination file, fail if it already exists */ RtlInitUnicodeString(&UnicodeString, DestName); InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); NtStatus = NtCreateFile(&DestFile, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus); /* If file exists, ask to overwrite file */ if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName)) { /* Create destination file, overwrite if it already exists */ NtStatus = NtCreateFile(&DestFile, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE, FILE_SYNCHRONOUS_IO_ALERT, NULL, 0); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus); return CAB_STATUS_CANNOT_CREATE; } } else { DPRINT("File (%S) exists\n", DestName); return CAB_STATUS_FILE_EXISTS; } } MaxDestFileSize.QuadPart = Search->File->FileSize; NtStatus = NtCreateSection(&DestFileSection, SECTION_ALL_ACCESS, 0, &MaxDestFileSize, PAGE_READWRITE, SEC_COMMIT, DestFile); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateSection failed: %x\n", NtStatus); Status = CAB_STATUS_NOMEMORY; goto CloseDestFile; } DestFileBuffer = 0; DestFileSize = 0; NtStatus = NtMapViewOfSection(DestFileSection, NtCurrentProcess(), &DestFileBuffer, 0, 0, 0, &DestFileSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtMapViewOfSection failed: %x\n", NtStatus); Status = CAB_STATUS_NOMEMORY; goto CloseDestFileSection; } CurrentDestBuffer = DestFileBuffer; if (!ConvertDosDateTimeToFileTime(Search->File->FileDate, Search->File->FileTime, &FileTime)) { DPRINT("DosDateTimeToFileTime() failed\n"); Status = CAB_STATUS_CANNOT_WRITE; goto UnmapDestFile; } NtStatus = NtQueryInformationFile(DestFile, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus); } else { memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME)); NtStatus = NtSetInformationFile(DestFile, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus); } } SetAttributesOnFile(Search->File, DestFile); /* Call extract event handler */ if (ExtractHandler != NULL) { ExtractHandler(Search->File, DestName); } /* find the starting block of the file start with the first data block of the folder */ CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset + FileBuffer); CurrentOffset = 0; while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset) { /* walk the data blocks until we reach the one containing the start of the file */ CurrentOffset += CFData->UncompSize; CFData = (PCFDATA)((char *)(CFData + 1) + DataReserved + CFData->CompSize); } /* now decompress and discard any data in the block before the start of the file */ /* start of comp data */ CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved; RemainingBlock = CFData->CompSize; InputLength = RemainingBlock; while (CurrentOffset < Search->File->FileOffset) { /* compute remaining uncomp bytes to start of file, bounded by sizeof junk */ OutputLength = Search->File->FileOffset - CurrentOffset; if (OutputLength > (LONG)sizeof(Junk)) OutputLength = sizeof (Junk); /* negate to signal NOT end of block */ OutputLength = -OutputLength; CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength); /* add the uncomp bytes extracted to current folder offset */ CurrentOffset += OutputLength; /* add comp bytes consumed to CurrentBuffer */ CurrentBuffer += InputLength; /* subtract bytes consumed from bytes remaining in block */ RemainingBlock -= InputLength; /* neg for resume decompression of the same block */ InputLength = -RemainingBlock; } /* now CurrentBuffer points to the first comp byte of the file, so we can begin decompressing */ /* Size = remaining uncomp bytes of the file to decompress */ Size = Search->File->FileSize; while (Size > 0) { OutputLength = Size; DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n", CurrentBuffer, RemainingBlock, Size); Status = CodecUncompress(CurrentDestBuffer, CurrentBuffer, &InputLength, &OutputLength); if (Status != CS_SUCCESS) { DPRINT("Cannot uncompress block\n"); if (Status == CS_NOMEMORY) Status = CAB_STATUS_NOMEMORY; Status = CAB_STATUS_INVALID_CAB; goto UnmapDestFile; } /* advance dest buffer by bytes produced */ CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength); /* advance src buffer by bytes consumed */ CurrentBuffer += InputLength; /* reduce remaining file bytes by bytes produced */ Size -= OutputLength; /* reduce remaining block size by bytes consumed */ RemainingBlock -= InputLength; if (RemainingBlock == 0) { /* used up this block, move on to the next */ DPRINT("Out of block data\n"); CFData = (PCFDATA)CurrentBuffer; RemainingBlock = CFData->CompSize; CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved; InputLength = RemainingBlock; } } Status = CAB_STATUS_SUCCESS; UnmapDestFile: NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer); CloseDestFileSection: NtClose(DestFileSection); CloseDestFile: NtClose(DestFile); return Status; }
VOID GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData, BOOL Defaults) { NTSTATUS Status; PCONSRV_CONSOLE Console = GuiData->Console; PCONSOLE_PROCESS_DATA ProcessData; HANDLE hSection = NULL, hClientSection = NULL; PVOID ThreadParameter = NULL; // Is either hClientSection or the console window handle, // depending on whether we display the default settings or // the settings of a particular console. DPRINT("GuiConsoleShowConsoleProperties entered\n"); if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return; /* Get the console leader process, our client */ ProcessData = ConSrvGetConsoleLeaderProcess(Console); /* * Be sure we effectively have a properties dialog routine (that launches * the console control panel applet). It resides in kernel32.dll (client). */ if (ProcessData->PropRoutine == NULL) goto Quit; /* * Create a memory section to be shared with the console control panel applet * in the case we are displaying the settings of a particular console. * In that case the ThreadParameter is the hClientSection handle. * In the case we display the default console parameters, we don't need to * create a memory section. We just need to open the applet, and in this case * the ThreadParameter is the parent window handle of the applet's window, * that is, the console window. */ if (!Defaults) { PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; LARGE_INTEGER SectionSize; ULONG ViewSize = 0; PCONSOLE_STATE_INFO pSharedInfo = NULL; /* * Create a memory section to share with the applet, and map it. */ SectionSize.QuadPart = sizeof(CONSOLE_STATE_INFO); // Standard size SectionSize.QuadPart += Console->OriginalTitle.Length; // Add the length in bytes of the console title string Status = NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &SectionSize, PAGE_READWRITE, SEC_COMMIT, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status); goto Quit; } Status = NtMapViewOfSection(hSection, NtCurrentProcess(), (PVOID*)&pSharedInfo, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status); goto Quit; } /* * Setup the shared console properties structure. */ /* Store the real size of the structure */ pSharedInfo->cbSize = SectionSize.QuadPart; /* * When we setup the settings of a particular console, the parent window * of the applet's window is the console window, and it is given via the * hWnd member of the shared console info structure. */ pSharedInfo->hWnd = GuiData->hWindow; /* Console information */ pSharedInfo->HistoryBufferSize = Console->HistoryBufferSize; pSharedInfo->NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; pSharedInfo->HistoryNoDup = Console->HistoryNoDup; pSharedInfo->QuickEdit = Console->QuickEdit; pSharedInfo->InsertMode = Console->InsertMode; /// pSharedInfo->InputBufferSize = 0; pSharedInfo->ScreenBufferSize = ActiveBuffer->ScreenBufferSize; pSharedInfo->WindowSize = ActiveBuffer->ViewSize; pSharedInfo->CursorSize = ActiveBuffer->CursorInfo.dwSize; if (GetType(ActiveBuffer) == TEXTMODE_BUFFER) { PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer; pSharedInfo->ScreenAttributes = Buffer->ScreenDefaultAttrib; pSharedInfo->PopupAttributes = Buffer->PopupDefaultAttrib; } else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) { // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer; DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n"); // FIXME: Gather defaults from the registry ? pSharedInfo->ScreenAttributes = DEFAULT_SCREEN_ATTRIB; pSharedInfo->PopupAttributes = DEFAULT_POPUP_ATTRIB ; } /// pSharedInfo->CodePage; /* GUI Information */ wcsncpy(pSharedInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE); pSharedInfo->FaceName[LF_FACESIZE - 1] = UNICODE_NULL; pSharedInfo->FontFamily = GuiData->GuiInfo.FontFamily; pSharedInfo->FontSize = GuiData->GuiInfo.FontSize; pSharedInfo->FontWeight = GuiData->GuiInfo.FontWeight; pSharedInfo->FullScreen = GuiData->GuiInfo.FullScreen; pSharedInfo->AutoPosition = GuiData->GuiInfo.AutoPosition; pSharedInfo->WindowPosition = GuiData->GuiInfo.WindowOrigin; /* Palette */ RtlCopyMemory(pSharedInfo->ColorTable, Console->Colors, sizeof(Console->Colors)); /* Copy the original title of the console and null-terminate it */ RtlCopyMemory(pSharedInfo->ConsoleTitle, Console->OriginalTitle.Buffer, Console->OriginalTitle.Length); pSharedInfo->ConsoleTitle[Console->OriginalTitle.Length / sizeof(WCHAR)] = UNICODE_NULL; /* Unmap the view */ NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo); /* Duplicate the section handle for the client */ Status = NtDuplicateObject(NtCurrentProcess(), hSection, ProcessData->Process->ProcessHandle, &hClientSection, 0, 0, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(Status)) { DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status); goto Quit; } /* For the settings of a particular console, use the shared client section handle as the thread parameter */ ThreadParameter = (PVOID)hClientSection; } else { /* For the default settings, use the console window handle as the thread parameter */ ThreadParameter = (PVOID)GuiData->hWindow; } /* Start the console control panel applet */ _SEH2_TRY { HANDLE Thread = NULL; _SEH2_TRY { Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0, ProcessData->PropRoutine, ThreadParameter, 0, NULL); if (NULL == Thread) { DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError()); } else { DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process); } } _SEH2_FINALLY { CloseHandle(Thread); } _SEH2_END; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status); } _SEH2_END; Quit: /* We have finished, close the section handle if any */ if (hSection) NtClose(hSection); LeaveCriticalSection(&Console->Lock); return; }