/* Last handle to a file object is closed */ NTSTATUS NTAPI FatiCleanup(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) { PIO_STACK_LOCATION IrpSp; PFILE_OBJECT FileObject; TYPE_OF_OPEN TypeOfOpen; PSHARE_ACCESS ShareAccess; BOOLEAN SendUnlockNotification = FALSE; PLARGE_INTEGER TruncateSize = NULL; //LARGE_INTEGER LocalTruncateSize; BOOLEAN AcquiredVcb = FALSE, AcquiredFcb = FALSE; NTSTATUS Status; PVCB Vcb; PFCB Fcb; PCCB Ccb; IrpSp = IoGetCurrentIrpStackLocation( Irp ); DPRINT("FatiCleanup\n"); DPRINT("\tIrp = %p\n", Irp); DPRINT("\t->FileObject = %p\n", IrpSp->FileObject); FileObject = IrpSp->FileObject; TypeOfOpen = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); if (TypeOfOpen == UnopenedFileObject) { DPRINT1("Unopened File Object\n"); FatCompleteRequest(IrpContext, Irp, STATUS_SUCCESS); return STATUS_SUCCESS; } if (FlagOn( FileObject->Flags, FO_CLEANUP_COMPLETE )) { /* Just flush the file */ if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) && FlagOn(FileObject->Flags, FO_FILE_MODIFIED) && !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED) && (TypeOfOpen == UserFileOpen)) { //Status = FatFlushFile(IrpContext, Fcb, Flush); //if (!NT_SUCCESS(Status)) FatNormalizeAndRaiseStatus(IrpContext, Status); UNIMPLEMENTED; } FatCompleteRequest(IrpContext, Irp, STATUS_SUCCESS); return STATUS_SUCCESS; } if (TypeOfOpen == UserFileOpen || TypeOfOpen == UserDirectoryOpen) { ASSERT(Fcb != NULL); (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb); AcquiredFcb = TRUE; /* Set FCB flags according to DELETE_ON_CLOSE */ if (FlagOn(Ccb->Flags, CCB_DELETE_ON_CLOSE)) { ASSERT(FatNodeType(Fcb) != FAT_NTC_ROOT_DCB); SetFlag(Fcb->State, FCB_STATE_DELETE_ON_CLOSE); /* Issue a notification */ if (TypeOfOpen == UserDirectoryOpen) { FsRtlNotifyFullChangeDirectory(Vcb->NotifySync, &Vcb->NotifyList, FileObject->FsContext, NULL, FALSE, FALSE, 0, NULL, NULL, NULL); } } /* If file should be deleted, acquire locks */ if ((Fcb->UncleanCount == 1) && FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && (Fcb->Condition != FcbBad) && !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) { FatReleaseFcb(IrpContext, Fcb); AcquiredFcb = FALSE; (VOID)FatAcquireExclusiveVcb(IrpContext, Vcb); AcquiredVcb = TRUE; (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb); AcquiredFcb = TRUE; } } /* Acquire VCB lock if it was a volume open */ if (TypeOfOpen == UserVolumeOpen) { (VOID)FatAcquireExclusiveVcb(IrpContext, Vcb); AcquiredVcb = TRUE; } /* Cleanup all notifications */ if (TypeOfOpen == UserDirectoryOpen) { FsRtlNotifyCleanup(Vcb->NotifySync, &Vcb->NotifyList, Ccb); } if (Fcb) { //TODO: FatVerifyFcb } switch (TypeOfOpen) { case DirectoryFile: case VirtualVolumeFile: DPRINT1("Cleanup VirtualVolumeFile/DirectoryFile\n"); ShareAccess = NULL; break; case UserVolumeOpen: DPRINT("Cleanup UserVolumeOpen\n"); if (FlagOn(Ccb->Flags, CCB_COMPLETE_DISMOUNT)) { FatCheckForDismount( IrpContext, Vcb, TRUE ); } else if (FileObject->WriteAccess && FlagOn(FileObject->Flags, FO_FILE_MODIFIED)) { UNIMPLEMENTED; } /* Release the volume and send notification */ if (FlagOn(Vcb->State, VCB_STATE_FLAG_LOCKED) && (Vcb->FileObjectWithVcbLocked == FileObject)) { UNIMPLEMENTED; SendUnlockNotification = TRUE; } ShareAccess = &Vcb->ShareAccess; break; case EaFile: DPRINT1("Cleanup EaFileObject\n"); ShareAccess = NULL; break; case UserDirectoryOpen: DPRINT("Cleanup UserDirectoryOpen\n"); ShareAccess = &Fcb->ShareAccess; /* Should it be a delayed close? */ if ((Fcb->UncleanCount == 1) && (Fcb->OpenCount == 1) && (Fcb->Dcb.DirectoryFileOpenCount == 0) && !FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && Fcb->Condition == FcbGood) { /* Yes, a delayed one */ SetFlag(Fcb->State, FCB_STATE_DELAY_CLOSE); } if (VcbGood == Vcb->Condition) { //FatUpdateDirentFromFcb( IrpContext, FileObject, Fcb, Ccb ); //TODO: Actually update dirent } if ((Fcb->UncleanCount == 1) && (FatNodeType(Fcb) == FAT_NTC_DCB) && (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE)) && (Fcb->Condition != FcbBad) && !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) { UNIMPLEMENTED; } /* Decrement unclean counter */ ASSERT(Fcb->UncleanCount != 0); Fcb->UncleanCount--; break; case UserFileOpen: DPRINT("Cleanup UserFileOpen\n"); ShareAccess = &Fcb->ShareAccess; /* Should it be a delayed close? */ if ((FileObject->SectionObjectPointer->DataSectionObject == NULL) && (FileObject->SectionObjectPointer->ImageSectionObject == NULL) && (Fcb->UncleanCount == 1) && (Fcb->OpenCount == 1) && !FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && Fcb->Condition == FcbGood) { /* Yes, a delayed one */ //SetFlag(Fcb->State, FCB_STATE_DELAY_CLOSE); DPRINT1("Setting a delay on close for some reason for FCB %p, FF handle %p, file name '%wZ'\n", Fcb, Fcb->FatHandle, &Fcb->FullFileName); } /* Unlock all file locks */ FsRtlFastUnlockAll(&Fcb->Fcb.Lock, FileObject, IoGetRequestorProcess(Irp), NULL); if (Vcb->Condition == VcbGood) { if (Fcb->Condition != FcbBad) { //FatUpdateDirentFromFcb( IrpContext, FileObject, Fcb, Ccb ); // TODO: Update on-disk structures } if (Fcb->UncleanCount == 1 && Fcb->Condition != FcbBad) { //DELETE_CONTEXT DeleteContext; /* Should this file be deleted on close? */ if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) { UNIMPLEMENTED; } else { if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE) && (Fcb->Header.ValidDataLength.LowPart < Fcb->Header.FileSize.LowPart)) { #if 0 ULONG ValidDataLength; ValidDataLength = Fcb->Header.ValidDataLength.LowPart; if (ValidDataLength < Fcb->ValidDataToDisk) { ValidDataLength = Fcb->ValidDataToDisk; } if (ValidDataLength < Fcb->Header.FileSize.LowPart) { FatZeroData( IrpContext, Vcb, FileObject, ValidDataLength, Fcb->Header.FileSize.LowPart - ValidDataLength ); Fcb->ValidDataToDisk = Fcb->Header.ValidDataLength.LowPart = Fcb->Header.FileSize.LowPart; if (CcIsFileCached(FileObject)) { CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize); } } #endif DPRINT1("Zeroing out data is not implemented\n"); } } /* Should the file be truncated on close? */ if (FlagOn(Fcb->State, FCB_STATE_TRUNCATE_ON_CLOSE)) { if (Vcb->Condition == VcbGood) { // TODO: Actually truncate the file allocation UNIMPLEMENTED; } /* Remove truncation flag */ Fcb->State &= ~FCB_STATE_TRUNCATE_ON_CLOSE; } /* Check again if it should be deleted */ if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && Fcb->Header.AllocationSize.LowPart == 0) { FatNotifyReportChange(IrpContext, Vcb, Fcb, FILE_NOTIFY_CHANGE_FILE_NAME, FILE_ACTION_REMOVED); } /* Remove the entry from the splay table if the file was deleted */ if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE)) { FatRemoveNames(IrpContext, Fcb); } } } ASSERT(Fcb->UncleanCount != 0); Fcb->UncleanCount--; if (!FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED)) { ASSERT(Fcb->NonCachedUncleanCount != 0); Fcb->NonCachedUncleanCount--; } if (FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED) && (Fcb->NonCachedUncleanCount != 0) && (Fcb->NonCachedUncleanCount == Fcb->UncleanCount) && (Fcb->SectionObjectPointers.DataSectionObject != NULL)) { CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL); /* Acquire and release PagingIo to get in sync with lazy writer */ ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE); ExReleaseResourceLite(Fcb->Header.PagingIoResource); CcPurgeCacheSection(&Fcb->SectionObjectPointers, NULL, 0, FALSE); } if (Fcb->Condition == FcbBad) { //TruncateSize = &FatLargeZero; UNIMPLEMENTED; } /* Cleanup the cache map */ CcUninitializeCacheMap(FileObject, TruncateSize, NULL); break; default: KeBugCheckEx(FAT_FILE_SYSTEM, __LINE__, (ULONG_PTR)TypeOfOpen, 0, 0); } /* Cleanup the share access */ if (ShareAccess) { DPRINT("Cleaning up the share access\n"); IoRemoveShareAccess(FileObject, ShareAccess); } if (TypeOfOpen == UserFileOpen) { /* Update oplocks */ FsRtlCheckOplock(&Fcb->Fcb.Oplock, Irp, IrpContext, NULL, NULL); Fcb->Header.IsFastIoPossible = FatIsFastIoPossible(Fcb); } /* Set the FO_CLEANUP_COMPLETE flag */ SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE); Status = STATUS_SUCCESS; // TODO: Unpin repinned BCBs //FatUnpinRepinnedBcbs(IrpContext); /* Flush the volume if necessary */ if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) && !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) { UNIMPLEMENTED; } /* Cleanup */ if (AcquiredFcb) FatReleaseFcb(IrpContext, Fcb); if (AcquiredVcb) FatReleaseVcb(IrpContext, Vcb); /* Send volume notification */ if (SendUnlockNotification) FsRtlNotifyVolumeEvent(FileObject, FSRTL_VOLUME_UNLOCK); return Status; }
NTSTATUS NTAPI IntInitializeVideoAddressSpace(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); NTSTATUS Status; HANDLE PhysMemHandle; PVOID BaseAddress; LARGE_INTEGER Offset; SIZE_T ViewSize; CHAR IVTAndBda[1024+256]; /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */ BaseAddress = 0; ViewSize = 1024 * 1024; Status = ZwFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &ViewSize, MEM_RELEASE); if (!NT_SUCCESS(Status)) { DPRINT1("Couldn't unmap reserved memory (%x)\n", Status); return 0; } /* Open the physical memory section */ InitializeObjectAttributes(&ObjectAttributes, &PhysMemName, 0, NULL, NULL); Status = ZwOpenSection(&PhysMemHandle, SECTION_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("Couldn't open \\Device\\PhysicalMemory\n"); return Status; } /* Map the BIOS and device registers into the address space */ Offset.QuadPart = 0xa0000; ViewSize = 0x100000 - 0xa0000; BaseAddress = (PVOID)0xa0000; Status = ZwMapViewOfSection(PhysMemHandle, NtCurrentProcess(), &BaseAddress, 0, ViewSize, &Offset, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Couldn't map physical memory (%x)\n", Status); ZwClose(PhysMemHandle); return Status; } /* Close physical memory section handle */ ZwClose(PhysMemHandle); if (BaseAddress != (PVOID)0xa0000) { DPRINT1("Couldn't map physical memory at the right address (was %x)\n", BaseAddress); return STATUS_UNSUCCESSFUL; } /* Allocate some low memory to use for the non-BIOS * parts of the v86 mode address space */ BaseAddress = (PVOID)0x1; ViewSize = 0xa0000 - 0x1000; Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &BaseAddress, 0, &ViewSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status); return Status; } if (BaseAddress != (PVOID)0x0) { DPRINT1("Failed to allocate virtual memory at right address (was %x)\n", BaseAddress); return 0; } /* Get the real mode IVT and BDA from the kernel */ Status = NtVdmControl(VdmInitialize, IVTAndBda); if (!NT_SUCCESS(Status)) { DPRINT1("NtVdmControl failed (status %x)\n", Status); return Status; } /* Return success */ return STATUS_SUCCESS; }
NTSTATUS SetAccountDomain(LPCWSTR DomainName, PSID DomainSid) { PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL; POLICY_ACCOUNT_DOMAIN_INFO Info; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; DOMAIN_NAME_INFORMATION DomainNameInfo; NTSTATUS Status; DPRINT("SYSSETUP: SetAccountDomain\n"); memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN, &PolicyHandle); if (Status != STATUS_SUCCESS) { DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status); return Status; } Status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (PVOID *)&OrigInfo); if (Status == STATUS_SUCCESS && OrigInfo != NULL) { if (DomainName == NULL) { Info.DomainName.Buffer = OrigInfo->DomainName.Buffer; Info.DomainName.Length = OrigInfo->DomainName.Length; Info.DomainName.MaximumLength = OrigInfo->DomainName.MaximumLength; } else { Info.DomainName.Buffer = (LPWSTR)DomainName; Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR); } if (DomainSid == NULL) Info.DomainSid = OrigInfo->DomainSid; else Info.DomainSid = DomainSid; } else { Info.DomainName.Buffer = (LPWSTR)DomainName; Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR); Info.DomainSid = DomainSid; } Status = LsaSetInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (PVOID)&Info); if (Status != STATUS_SUCCESS) { DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status); } if (OrigInfo != NULL) LsaFreeMemory(OrigInfo); LsaClose(PolicyHandle); DomainNameInfo.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); DomainNameInfo.DomainName.MaximumLength = (wcslen(DomainName) + 1) * sizeof(WCHAR); DomainNameInfo.DomainName.Buffer = (LPWSTR)DomainName; Status = SamConnect(NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (NT_SUCCESS(Status)) { Status = SamOpenDomain(ServerHandle, DOMAIN_WRITE_OTHER_PARAMETERS, Info.DomainSid, &DomainHandle); if (NT_SUCCESS(Status)) { Status = SamSetInformationDomain(DomainHandle, DomainNameInformation, (PVOID)&DomainNameInfo); if (!NT_SUCCESS(Status)) { DPRINT1("SamSetInformationDomain failed (Status: 0x%08lx)\n", Status); } SamCloseHandle(DomainHandle); } else { DPRINT1("SamOpenDomain failed (Status: 0x%08lx)\n", Status); } SamCloseHandle(ServerHandle); } return Status; }
NTSTATUS SetAdministratorPassword(LPCWSTR Password) { PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL; PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL; USER_SET_PASSWORD_INFORMATION PasswordInfo; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle = NULL; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; SAM_HANDLE UserHandle = NULL; NTSTATUS Status; DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password); memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN, &PolicyHandle); if (Status != STATUS_SUCCESS) { DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status); return Status; } Status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (PVOID *)&OrigInfo); if (!NT_SUCCESS(Status)) { DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status); goto done; } Status = SamConnect(NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status); goto done; } Status = SamOpenDomain(ServerHandle, DOMAIN_LOOKUP, OrigInfo->DomainSid, &DomainHandle); if (!NT_SUCCESS(Status)) { DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status); goto done; } Status = SamOpenUser(DomainHandle, USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL, DOMAIN_USER_RID_ADMIN, &UserHandle); if (!NT_SUCCESS(Status)) { DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status); goto done; } RtlInitUnicodeString(&PasswordInfo.Password, Password); PasswordInfo.PasswordExpired = FALSE; Status = SamSetInformationUser(UserHandle, UserSetPasswordInformation, (PVOID)&PasswordInfo); if (!NT_SUCCESS(Status)) { DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status); goto done; } Status = SamQueryInformationUser(UserHandle, UserAccountNameInformation, (PVOID*)&AccountNameInfo); if (!NT_SUCCESS(Status)) { DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status); goto done; } AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, AccountNameInfo->UserName.Length + sizeof(WCHAR)); if (AdminInfo.Name != NULL) RtlCopyMemory(AdminInfo.Name, AccountNameInfo->UserName.Buffer, AccountNameInfo->UserName.Length); AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, OrigInfo->DomainName.Length + sizeof(WCHAR)); if (AdminInfo.Domain != NULL) RtlCopyMemory(AdminInfo.Domain, OrigInfo->DomainName.Buffer, OrigInfo->DomainName.Length); AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(), 0, (wcslen(Password) + 1) * sizeof(WCHAR)); if (AdminInfo.Password != NULL) wcscpy(AdminInfo.Password, Password); DPRINT("Administrator Name: %S\n", AdminInfo.Name); DPRINT("Administrator Domain: %S\n", AdminInfo.Domain); DPRINT("Administrator Password: %S\n", AdminInfo.Password); done: if (AccountNameInfo != NULL) SamFreeMemory(AccountNameInfo); if (OrigInfo != NULL) LsaFreeMemory(OrigInfo); if (PolicyHandle != NULL) LsaClose(PolicyHandle); if (UserHandle != NULL) SamCloseHandle(UserHandle); if (DomainHandle != NULL) SamCloseHandle(DomainHandle); if (ServerHandle != NULL) SamCloseHandle(ServerHandle); DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status); return Status; }
/* * @unimplemented */ NTSTATUS NTAPI MmAdjustWorkingSetSize(IN SIZE_T WorkingSetMinimumInBytes, IN SIZE_T WorkingSetMaximumInBytes, IN ULONG SystemCache, IN BOOLEAN IncreaseOkay) { SIZE_T MinimumWorkingSetSize, MaximumWorkingSetSize; SSIZE_T Delta; PMMSUPPORT Ws; NTSTATUS Status; /* Check for special case: empty the working set */ if ((WorkingSetMinimumInBytes == -1) && (WorkingSetMaximumInBytes == -1)) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } /* Assume success */ Status = STATUS_SUCCESS; /* Get the working set and lock it */ Ws = &PsGetCurrentProcess()->Vm; MiLockWorkingSet(PsGetCurrentThread(), Ws); /* Calculate the actual minimum and maximum working set size to set */ MinimumWorkingSetSize = (WorkingSetMinimumInBytes != 0) ? (WorkingSetMinimumInBytes / PAGE_SIZE) : Ws->MinimumWorkingSetSize; MaximumWorkingSetSize = (WorkingSetMaximumInBytes != 0) ? (WorkingSetMaximumInBytes / PAGE_SIZE) : Ws->MaximumWorkingSetSize; /* Check if the new maximum exceeds the global maximum */ if (MaximumWorkingSetSize > MmMaximumWorkingSetSize) { MaximumWorkingSetSize = MmMaximumWorkingSetSize; Status = STATUS_WORKING_SET_LIMIT_RANGE; } /* Check if the new minimum is below the global minimum */ if (MinimumWorkingSetSize < MmMinimumWorkingSetSize) { MinimumWorkingSetSize = MmMinimumWorkingSetSize; Status = STATUS_WORKING_SET_LIMIT_RANGE; } /* Check if the new minimum exceeds the new maximum */ if (MinimumWorkingSetSize > MaximumWorkingSetSize) { DPRINT1("MinimumWorkingSetSize > MaximumWorkingSetSize\n"); Status = STATUS_BAD_WORKING_SET_LIMIT; goto Cleanup; } /* Calculate the minimum WS size adjustment and check if we increase */ Delta = MinimumWorkingSetSize - Ws->MinimumWorkingSetSize; if (Delta > 0) { /* Is increasing ok? */ if (!IncreaseOkay) { DPRINT1("Privilege for WS size increase not held\n"); Status = STATUS_PRIVILEGE_NOT_HELD; goto Cleanup; } /* Check if the number of available pages is large enough */ if (((SIZE_T)Delta / 1024) > (MmAvailablePages - 128)) { DPRINT1("Not enough available pages\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } /* Check if there are enough resident available pages */ if ((SIZE_T)Delta > (MmResidentAvailablePages - MmSystemLockPagesCount - 256)) { DPRINT1("Not enough resident pages\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } } /* Update resident available pages */ if (Delta != 0) { InterlockedExchangeAddSizeT(&MmResidentAvailablePages, -Delta); } /* Calculate new pages above minimum WS size */ Delta += max((SSIZE_T)Ws->WorkingSetSize - MinimumWorkingSetSize, 0); /* Subtract old pages above minimum WS size */ Delta -= max((SSIZE_T)Ws->WorkingSetSize - Ws->MinimumWorkingSetSize, 0); /* If it changed, add it to the global variable */ if (Delta != 0) { InterlockedExchangeAddSizeT(&MmPagesAboveWsMinimum, Delta); } /* Set the new working set size */ Ws->MinimumWorkingSetSize = MinimumWorkingSetSize; Ws->MaximumWorkingSetSize = MaximumWorkingSetSize; Cleanup: /* Unlock the working set and return the status */ MiUnlockWorkingSet(PsGetCurrentThread(), Ws); return Status; }
static VOID InstallPrivileges(VOID) { HINF hSecurityInf = INVALID_HANDLE_VALUE; LSA_OBJECT_ATTRIBUTES ObjectAttributes; WCHAR szPrivilegeString[256]; WCHAR szSidString[256]; INFCONTEXT InfContext; DWORD i; PRIVILEGE_SET PrivilegeSet; PSID AccountSid; NTSTATUS Status; LSA_HANDLE PolicyHandle = NULL; LSA_HANDLE AccountHandle; DPRINT("InstallPrivileges()\n"); hSecurityInf = SetupOpenInfFileW(L"defltws.inf", //szNameBuffer, NULL, INF_STYLE_WIN4, NULL); if (hSecurityInf == INVALID_HANDLE_VALUE) { DPRINT1("SetupOpenInfFileW failed\n"); return; } memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_CREATE_ACCOUNT, &PolicyHandle); if (!NT_SUCCESS(Status)) { DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status); goto done; } if (!SetupFindFirstLineW(hSecurityInf, L"Privilege Rights", NULL, &InfContext)) { DPRINT1("SetupFindfirstLineW failed\n"); goto done; } PrivilegeSet.PrivilegeCount = 1; PrivilegeSet.Control = 0; do { /* Retrieve the privilege name */ if (!SetupGetStringFieldW(&InfContext, 0, szPrivilegeString, 256, NULL)) { DPRINT1("SetupGetStringFieldW() failed\n"); goto done; } DPRINT("Privilege: %S\n", szPrivilegeString); if (!LookupPrivilegeValueW(NULL, szPrivilegeString, &(PrivilegeSet.Privilege[0].Luid))) { DPRINT1("LookupPrivilegeNameW() failed\n"); goto done; } PrivilegeSet.Privilege[0].Attributes = 0; for (i = 0; i < SetupGetFieldCount(&InfContext); i++) { if (!SetupGetStringFieldW(&InfContext, i + 1, szSidString, 256, NULL)) { DPRINT1("SetupGetStringFieldW() failed\n"); goto done; } DPRINT("SID: %S\n", szSidString); if (!ConvertStringSidToSid(szSidString, &AccountSid)) { DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", szSidString, GetLastError()); continue; } Status = LsaOpenAccount(PolicyHandle, AccountSid, ACCOUNT_VIEW | ACCOUNT_ADJUST_PRIVILEGES, &AccountHandle); if (NT_SUCCESS(Status)) { Status = LsaAddPrivilegesToAccount(AccountHandle, &PrivilegeSet); if (!NT_SUCCESS(Status)) { DPRINT1("LsaAddPrivilegesToAccount() failed (Status %08lx)\n", Status); } LsaClose(AccountHandle); } LocalFree(AccountSid); } } while (SetupFindNextLine(&InfContext, &InfContext)); done: if (PolicyHandle != NULL) LsaClose(PolicyHandle); if (hSecurityInf != INVALID_HANDLE_VALUE) SetupCloseInfFile(hSecurityInf); }
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, %wZ\n", Status, &FileName); 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; }
NTSTATUS SetupExtractFile( PWCHAR CabinetFileName, PWCHAR SourceFileName, PWCHAR DestinationPathName) { ULONG CabStatus; DPRINT("SetupExtractFile(CabinetFileName %S, SourceFileName %S, DestinationPathName %S)\n", CabinetFileName, SourceFileName, DestinationPathName); if (HasCurrentCabinet) { DPRINT("CurrentCabinetName: %S\n", CurrentCabinetName); } if ((HasCurrentCabinet) && (wcscmp(CabinetFileName, CurrentCabinetName) == 0)) { DPRINT("Using same cabinet as last time\n"); /* Use our last location because the files should be sequential */ CabStatus = CabinetFindNextFileSequential(SourceFileName, &Search); if (CabStatus != CAB_STATUS_SUCCESS) { DPRINT("Sequential miss on file: %S\n", SourceFileName); /* Looks like we got unlucky */ CabStatus = CabinetFindFirst(SourceFileName, &Search); } } else { DPRINT("Using new cabinet\n"); if (HasCurrentCabinet) { CabinetCleanup(); } wcscpy(CurrentCabinetName, CabinetFileName); CabinetInitialize(); CabinetSetEventHandlers(NULL, NULL, NULL); CabinetSetCabinetName(CabinetFileName); CabStatus = CabinetOpen(); if (CabStatus == CAB_STATUS_SUCCESS) { DPRINT("Opened cabinet %S\n", CabinetGetCabinetName()); HasCurrentCabinet = TRUE; } else { DPRINT("Cannot open cabinet (%d)\n", CabStatus); return STATUS_UNSUCCESSFUL; } /* We have to start at the beginning here */ CabStatus = CabinetFindFirst(SourceFileName, &Search); } if (CabStatus != CAB_STATUS_SUCCESS) { DPRINT1("Unable to find '%S' in cabinet '%S'\n", SourceFileName, CabinetGetCabinetName()); return STATUS_UNSUCCESSFUL; } CabinetSetDestinationPath(DestinationPathName); CabStatus = CabinetExtractFile(&Search); if (CabStatus != CAB_STATUS_SUCCESS) { DPRINT("Cannot extract file %S (%d)\n", SourceFileName, CabStatus); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; }
VOID NTAPI INIT_FUNCTION HalpFixupPciSupportedRanges(IN ULONG BusCount) { ULONG i; PBUS_HANDLER Bus, ParentBus; /* Loop all buses */ for (i = 0; i < BusCount; i++) { /* Get PCI bus handler */ Bus = HalHandlerForBus(PCIBus, i); /* Loop all parent buses */ ParentBus = Bus->ParentHandler; while (ParentBus) { /* Should merge addresses */ if (!WarningsGiven[0]++) DPRINT1("Found parent bus (indicating PCI Bridge). PCI devices may fail!\n"); /* Check the next parent */ ParentBus = ParentBus->ParentHandler; } } /* Loop all buses again */ for (i = 0; i < BusCount; i++) { /* Get PCI bus handler */ Bus = HalHandlerForBus(PCIBus, i); /* Check if this is a PCI 2.2 Bus with Subtractive Decode */ if (!((PPCIPBUSDATA)Bus->BusData)->Subtractive) { /* Loop all parent buses */ ParentBus = Bus->ParentHandler; while (ParentBus) { /* But check only PCI parent buses specifically */ if (ParentBus->InterfaceType == PCIBus) { /* Should trim addresses */ if (!WarningsGiven[1]++) DPRINT1("Found parent PCI Bus (indicating PCI-to-PCI Bridge). PCI devices may fail!\n"); } /* Check the next parent */ ParentBus = ParentBus->ParentHandler; } } } /* Loop buses one last time */ for (i = 0; i < BusCount; i++) { /* Get the PCI bus handler */ Bus = HalHandlerForBus(PCIBus, i); /* Sort and combine (trim) bus address range information */ DPRINT("Warning: Bus addresses not being optimized!\n"); } }
NTSTATUS CMAPI HvpInitializeMemoryHive( PHHIVE Hive, PVOID ChunkBase) { SIZE_T BlockIndex; PHBIN Bin, NewBin; ULONG i; ULONG BitmapSize; PULONG BitmapBuffer; SIZE_T ChunkSize; ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length; DPRINT("ChunkSize: %lx\n", ChunkSize); if (ChunkSize < sizeof(HBASE_BLOCK) || !HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase)) { DPRINT1("Registry is corrupt: ChunkSize %lu < sizeof(HBASE_BLOCK) %lu, " "or HvpVerifyHiveHeader() failed\n", ChunkSize, (SIZE_T)sizeof(HBASE_BLOCK)); return STATUS_REGISTRY_CORRUPT; } Hive->BaseBlock = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM); if (Hive->BaseBlock == NULL) { return STATUS_NO_MEMORY; } RtlCopyMemory(Hive->BaseBlock, ChunkBase, sizeof(HBASE_BLOCK)); /* * Build a block list from the in-memory chunk and copy the data as * we go. */ Hive->Storage[Stable].Length = (ULONG)(ChunkSize / HV_BLOCK_SIZE); Hive->Storage[Stable].BlockList = Hive->Allocate(Hive->Storage[Stable].Length * sizeof(HMAP_ENTRY), FALSE, TAG_CM); if (Hive->Storage[Stable].BlockList == NULL) { DPRINT1("Allocating block list failed\n"); Hive->Free(Hive->BaseBlock, 0); return STATUS_NO_MEMORY; } for (BlockIndex = 0; BlockIndex < Hive->Storage[Stable].Length; ) { Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HV_BLOCK_SIZE); if (Bin->Signature != HV_BIN_SIGNATURE || (Bin->Size % HV_BLOCK_SIZE) != 0) { DPRINT1("Invalid bin at BlockIndex %lu, Signature 0x%x, Size 0x%x\n", (unsigned long)BlockIndex, (unsigned)Bin->Signature, (unsigned)Bin->Size); Hive->Free(Hive->BaseBlock, 0); Hive->Free(Hive->Storage[Stable].BlockList, 0); return STATUS_REGISTRY_CORRUPT; } NewBin = Hive->Allocate(Bin->Size, TRUE, TAG_CM); if (NewBin == NULL) { Hive->Free(Hive->BaseBlock, 0); Hive->Free(Hive->Storage[Stable].BlockList, 0); return STATUS_NO_MEMORY; } Hive->Storage[Stable].BlockList[BlockIndex].BinAddress = (ULONG_PTR)NewBin; Hive->Storage[Stable].BlockList[BlockIndex].BlockAddress = (ULONG_PTR)NewBin; RtlCopyMemory(NewBin, Bin, Bin->Size); if (Bin->Size > HV_BLOCK_SIZE) { for (i = 1; i < Bin->Size / HV_BLOCK_SIZE; i++) { Hive->Storage[Stable].BlockList[BlockIndex + i].BinAddress = (ULONG_PTR)NewBin; Hive->Storage[Stable].BlockList[BlockIndex + i].BlockAddress = ((ULONG_PTR)NewBin + (i * HV_BLOCK_SIZE)); } } BlockIndex += Bin->Size / HV_BLOCK_SIZE; } if (HvpCreateHiveFreeCellList(Hive)) { HvpFreeHiveBins(Hive); Hive->Free(Hive->BaseBlock, 0); return STATUS_NO_MEMORY; } BitmapSize = ROUND_UP(Hive->Storage[Stable].Length, sizeof(ULONG) * 8) / 8; BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE, TAG_CM); if (BitmapBuffer == NULL) { HvpFreeHiveBins(Hive); Hive->Free(Hive->BaseBlock, 0); return STATUS_NO_MEMORY; } RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8); RtlClearAllBits(&Hive->DirtyVector); return STATUS_SUCCESS; }
NTSTATUS Bus_FDO_Power ( PFDO_DEVICE_DATA Data, PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; POWER_STATE powerState; POWER_STATE_TYPE powerType; PIO_STACK_LOCATION stack; ULONG AcpiState; ACPI_STATUS AcpiStatus; SYSTEM_POWER_STATE oldPowerState; stack = IoGetCurrentIrpStackLocation (Irp); powerType = stack->Parameters.Power.Type; powerState = stack->Parameters.Power.State; if (stack->MinorFunction == IRP_MN_SET_POWER) { DPRINT("\tRequest to set %s state to %s\n", ((powerType == SystemPowerState) ? "System" : "Device"), ((powerType == SystemPowerState) ? \ DbgSystemPowerString(powerState.SystemState) :\ DbgDevicePowerString(powerState.DeviceState))); } if (powerType == SystemPowerState) { switch (powerState.SystemState) { case PowerSystemSleeping1: AcpiState = ACPI_STATE_S1; break; case PowerSystemSleeping2: AcpiState = ACPI_STATE_S2; break; case PowerSystemSleeping3: AcpiState = ACPI_STATE_S3; break; case PowerSystemHibernate: AcpiState = ACPI_STATE_S4; break; case PowerSystemShutdown: AcpiState = ACPI_STATE_S5; break; default: AcpiState = ACPI_STATE_UNKNOWN; ASSERT(FALSE); break; } oldPowerState = Data->Common.SystemPowerState; Data->Common.SystemPowerState = powerState.SystemState; AcpiStatus = acpi_suspend(AcpiState); if (!ACPI_SUCCESS(AcpiStatus)) { DPRINT1("Failed to enter sleep state %d (Status 0x%X)\n", AcpiState, AcpiStatus); Data->Common.SystemPowerState = oldPowerState; status = STATUS_UNSUCCESSFUL; } } PoStartNextPowerIrp (Irp); IoSkipCurrentIrpStackLocation(Irp); status = PoCallDriver (Data->NextLowerDriver, Irp); return status; }
BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput) { USHORT i; /* Initialize memory */ if (!MemInitialize()) { wprintf(L"Memory initialization failed.\n"); return FALSE; } /* Initialize I/O ports */ /* Initialize RAM */ /* Initialize the CPU */ /* Initialize the internal clock */ if (!ClockInitialize()) { wprintf(L"FATAL: Failed to initialize the clock\n"); EmulatorCleanup(); return FALSE; } /* Initialize the CPU */ CpuInitialize(); /* Initialize DMA */ DmaInitialize(); /* Initialize PIC, PIT, CMOS, PC Speaker and PS/2 */ PicInitialize(); PitInitialize(); PitSetOutFunction(0, NULL, PitChan0Out); PitSetOutFunction(1, NULL, PitChan1Out); PitSetOutFunction(2, NULL, PitChan2Out); CmosInitialize(); SpeakerInitialize(); PpiInitialize(); PS2Initialize(); /* Initialize the keyboard and mouse and connect them to their PS/2 ports */ KeyboardInit(0); MouseInit(1); /**************** ATTACH INPUT WITH CONSOLE *****************/ /* Create the task event */ VdmTaskEvent = CreateEventW(NULL, TRUE, FALSE, NULL); ASSERT(VdmTaskEvent != NULL); /* Start the input thread */ InputThread = CreateThread(NULL, 0, &ConsoleEventThread, ConsoleInput, 0, NULL); if (InputThread == NULL) { wprintf(L"FATAL: Failed to create the console input thread.\n"); EmulatorCleanup(); return FALSE; } ResumeEventThread(); /************************************************************/ /* Initialize the VGA */ if (!VgaInitialize(ConsoleOutput)) { wprintf(L"FATAL: Failed to initialize VGA support.\n"); EmulatorCleanup(); return FALSE; } /* Initialize the disk controller */ if (!DiskCtrlInitialize()) { wprintf(L"FATAL: Failed to completely initialize the disk controller.\n"); EmulatorCleanup(); return FALSE; } /* Mount the available floppy disks */ for (i = 0; i < ARRAYSIZE(GlobalSettings.FloppyDisks); ++i) { if (GlobalSettings.FloppyDisks[i].Length != 0 && GlobalSettings.FloppyDisks[i].Buffer && GlobalSettings.FloppyDisks[i].Buffer != '\0') { if (!MountDisk(FLOPPY_DISK, i, GlobalSettings.FloppyDisks[i].Buffer, FALSE)) { DPRINT1("Failed to mount floppy disk file '%wZ'.\n", &GlobalSettings.FloppyDisks[i]); RtlFreeUnicodeString(&GlobalSettings.FloppyDisks[i]); RtlInitEmptyUnicodeString(&GlobalSettings.FloppyDisks[i], NULL, 0); } } } /* * Mount the available hard disks. Contrary to floppies, failing * mounting a hard disk is considered as an unrecoverable error. */ for (i = 0; i < ARRAYSIZE(GlobalSettings.HardDisks); ++i) { if (GlobalSettings.HardDisks[i].Length != 0 && GlobalSettings.HardDisks[i].Buffer && GlobalSettings.HardDisks[i].Buffer != L'\0') { if (!MountDisk(HARD_DISK, i, GlobalSettings.HardDisks[i].Buffer, FALSE)) { wprintf(L"FATAL: Failed to mount hard disk file '%wZ'.\n", &GlobalSettings.HardDisks[i]); EmulatorCleanup(); return FALSE; } } } /* Refresh the menu state */ UpdateVdmMenuDisks(); /* Initialize the software callback system and register the emulator BOPs */ InitializeInt32(); RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop); // RegisterBop(BOP_UNSIMULATE, CpuUnsimulateBop); /* Initialize VDD support */ VDDSupInitialize(); return TRUE; }
static DWORD WINAPI ConsoleEventThread(LPVOID Parameter) { HANDLE ConsoleInput = (HANDLE)Parameter; HANDLE WaitHandles[2]; DWORD WaitResult; /* * For optimization purposes, Windows (and hence ReactOS, too, for * compatibility reasons) uses a static buffer if no more than five * input records are read. Otherwise a new buffer is used. * The client-side expects that we know this behaviour. * See consrv/coninput.c * * We exploit here this optimization by also using a buffer of 5 records. */ INPUT_RECORD InputRecords[5]; ULONG NumRecords, i; WaitHandles[0] = VdmTaskEvent; WaitHandles[1] = GetConsoleInputWaitHandle(); while (VdmRunning) { /* Make sure the task event is signaled */ WaitResult = WaitForMultipleObjects(ARRAYSIZE(WaitHandles), WaitHandles, TRUE, INFINITE); switch (WaitResult) { case WAIT_OBJECT_0 + 0: case WAIT_OBJECT_0 + 1: break; default: return GetLastError(); } /* Wait for an input record */ if (!ReadConsoleInputExW(ConsoleInput, InputRecords, ARRAYSIZE(InputRecords), &NumRecords, CONSOLE_READ_CONTINUE)) { DWORD LastError = GetLastError(); DPRINT1("Error reading console input (0x%p, %lu) - Error %lu\n", ConsoleInput, NumRecords, LastError); return LastError; } // ASSERT(NumRecords != 0); if (NumRecords == 0) { DPRINT1("Got NumRecords == 0!\n"); continue; } /* Dispatch the events */ for (i = 0; i < NumRecords; i++) { /* Check the event type */ switch (InputRecords[i].EventType) { /* * Hardware events */ case KEY_EVENT: KeyboardEventHandler(&InputRecords[i].Event.KeyEvent); break; case MOUSE_EVENT: MouseEventHandler(&InputRecords[i].Event.MouseEvent); break; case WINDOW_BUFFER_SIZE_EVENT: ScreenEventHandler(&InputRecords[i].Event.WindowBufferSizeEvent); break; /* * Interface events */ case MENU_EVENT: MenuEventHandler(&InputRecords[i].Event.MenuEvent); break; case FOCUS_EVENT: FocusEventHandler(&InputRecords[i].Event.FocusEvent); break; default: DPRINT1("Unknown input event type 0x%04x\n", InputRecords[i].EventType); break; } } /* Let the console subsystem queue some new events */ Sleep(10); } return 0; }
static VOID WINAPI EmulatorDebugBreakBop(LPWORD Stack) { DPRINT1("NTVDM: BOP_DEBUGGER\n"); DebugBreak(); }
/* * Runs the keyboard IOCTL_INTERNAL dispatch. */ NTSTATUS NTAPI i8042KbdInternalDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION Stack; PI8042_KEYBOARD_EXTENSION DeviceExtension; NTSTATUS Status; Stack = IoGetCurrentIrpStackLocation(Irp); Irp->IoStatus.Information = 0; DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; switch (Stack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_INTERNAL_KEYBOARD_CONNECT: { SIZE_T Size; PIO_WORKITEM WorkItem = NULL; PI8042_HOOK_WORKITEM WorkItemData = NULL; TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA)) { Status = STATUS_INVALID_PARAMETER; goto cleanup; } DeviceExtension->KeyboardData = *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); /* Send IOCTL_INTERNAL_I8042_HOOK_KEYBOARD to device stack */ WorkItem = IoAllocateWorkItem(DeviceObject); if (!WorkItem) { WARN_(I8042PRT, "IoAllocateWorkItem() failed\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } WorkItemData = ExAllocatePoolWithTag( NonPagedPool, sizeof(I8042_HOOK_WORKITEM), I8042PRT_TAG); if (!WorkItemData) { WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } WorkItemData->WorkItem = WorkItem; WorkItemData->Irp = Irp; /* Initialize extension */ DeviceExtension->Common.Type = Keyboard; Size = DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA); DeviceExtension->KeyboardBuffer = ExAllocatePoolWithTag( NonPagedPool, Size, I8042PRT_TAG); if (!DeviceExtension->KeyboardBuffer) { WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } RtlZeroMemory(DeviceExtension->KeyboardBuffer, Size); KeInitializeDpc( &DeviceExtension->DpcKeyboard, i8042KbdDpcRoutine, DeviceExtension); DeviceExtension->PowerWorkItem = IoAllocateWorkItem(DeviceObject); if (!DeviceExtension->PowerWorkItem) { WARN_(I8042PRT, "IoAllocateWorkItem() failed\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } DeviceExtension->DebugWorkItem = IoAllocateWorkItem(DeviceObject); if (!DeviceExtension->DebugWorkItem) { WARN_(I8042PRT, "IoAllocateWorkItem() failed\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } DeviceExtension->Common.PortDeviceExtension->KeyboardExtension = DeviceExtension; DeviceExtension->Common.PortDeviceExtension->Flags |= KEYBOARD_CONNECTED; IoMarkIrpPending(Irp); /* FIXME: DeviceExtension->KeyboardHook.IsrWritePort = ; */ DeviceExtension->KeyboardHook.QueueKeyboardPacket = i8042KbdQueuePacket; DeviceExtension->KeyboardHook.CallContext = DeviceExtension; IoQueueWorkItem(WorkItem, i8042SendHookWorkItem, DelayedWorkQueue, WorkItemData); Status = STATUS_PENDING; break; cleanup: if (DeviceExtension->KeyboardBuffer) ExFreePoolWithTag(DeviceExtension->KeyboardBuffer, I8042PRT_TAG); if (DeviceExtension->PowerWorkItem) IoFreeWorkItem(DeviceExtension->PowerWorkItem); if (DeviceExtension->DebugWorkItem) IoFreeWorkItem(DeviceExtension->DebugWorkItem); if (WorkItem) IoFreeWorkItem(WorkItem); if (WorkItemData) ExFreePoolWithTag(WorkItemData, I8042PRT_TAG); break; } case IOCTL_INTERNAL_KEYBOARD_DISCONNECT: { TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_DISCONNECT\n"); /* MSDN says that operation is to implemented. * To implement it, we just have to do: * DeviceExtension->KeyboardData.ClassService = NULL; */ Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: { TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_KEYBOARD\n"); /* Nothing to do here */ Status = STATUS_SUCCESS; break; } case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: { DPRINT1("IOCTL_KEYBOARD_QUERY_ATTRIBUTES not implemented\n"); #if 0 /* FIXME: KeyboardAttributes are not initialized anywhere */ TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"); if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES)) { Status = STATUS_BUFFER_TOO_SMALL; break; } *(PKEYBOARD_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer = DeviceExtension->KeyboardAttributes; Irp->IoStatus.Information = sizeof(KEYBOARD_ATTRIBUTES); Status = STATUS_SUCCESS; break; #endif Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_KEYBOARD_QUERY_TYPEMATIC: { DPRINT1("IOCTL_KEYBOARD_QUERY_TYPEMATIC not implemented\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_KEYBOARD_SET_TYPEMATIC: { DPRINT1("IOCTL_KEYBOARD_SET_TYPEMATIC not implemented\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: { TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n"); /* We should check the UnitID, but it's kind of pointless as * all keyboards are supposed to have the same one */ if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) { Status = STATUS_BUFFER_TOO_SMALL; } else { RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, &IndicatorTranslation, sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)); Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); Status = STATUS_SUCCESS; } break; } case IOCTL_KEYBOARD_QUERY_INDICATORS: { TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATORS\n"); if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { Status = STATUS_BUFFER_TOO_SMALL; } else { RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, &DeviceExtension->KeyboardIndicators, sizeof(KEYBOARD_INDICATOR_PARAMETERS)); Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS); Status = STATUS_SUCCESS; } break; } case IOCTL_KEYBOARD_SET_INDICATORS: { TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_SET_INDICATORS\n"); if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { Status = STATUS_BUFFER_TOO_SMALL; } else { RtlCopyMemory( &DeviceExtension->KeyboardIndicators, Irp->AssociatedIrp.SystemBuffer, sizeof(KEYBOARD_INDICATOR_PARAMETERS)); Status = STATUS_PENDING; IoMarkIrpPending(Irp); IoStartPacket(DeviceObject, Irp, NULL, NULL); } break; } default: { ERR_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode); ASSERT(FALSE); return ForwardIrpAndForget(DeviceObject, Irp); } } Irp->IoStatus.Status = Status; if (Status != STATUS_PENDING) IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }