Example #1
0
BOOL DemDispatch (ULONG iSvc)
{
#if DBG
    if(iSvc < SVC_DEMLASTSVC && (fShowSVCMsg & DEMSVCTRACE) &&
	 apfnSVC[iSvc] != demNotYetImplemented){
	sprintf(demDebugBuffer,"DemDispatch: Entering %s\n\tAX=%.4x BX=%.4x CX=%.4x DX=%.4x DI=%.4x SI=%.4x\n",
	       aSVCNames[iSvc],getAX(),getBX(),getCX(),getDX(),getDI(),getSI());
        OutputDebugStringOem(demDebugBuffer);
	sprintf(demDebugBuffer,"\tCS=%.4x IP=%.4x DS=%.4x ES=%.4x SS=%.4x SP=%.4x BP=%.4x\n",
                getCS(),getIP(), getDS(),getES(),getSS(),getSP(),getBP());
        OutputDebugStringOem(demDebugBuffer);
    }
#endif

    if (iSvc >= SVC_DEMLASTSVC){
#if DBG
	sprintf(demDebugBuffer,"Unimplemented SVC index %x\n",iSvc);
        OutputDebugStringOem(demDebugBuffer);
#endif
	setCF(1);
	return FALSE;
    }

    if (pHardErrPacket) {
	pHardErrPacket->vhe_fbInt24 = 0;
    }
    CurrentISVC = iSvc;
    (apfnSVC [iSvc])();


#if DBG
    if((fShowSVCMsg & DEMSVCTRACE)){
	sprintf(demDebugBuffer,"DemDispatch:On Leaving %s\n\tAX=%.4x BX=%.4x CX=%.4x DX=%.4x DI=%.4x SI=%.4x\n",
               aSVCNames[iSvc],getAX(),getBX(),getCX(),getDX(),getDI(),getSI());
        OutputDebugStringOem(demDebugBuffer);
	sprintf(demDebugBuffer,"\tCS=%.4x IP=%.4x DS=%.4x ES=%.4x SS=%.4x SP=%.4x BP=%.4x CF=%x\n",
                getCS(),getIP(), getDS(),getES(),getSS(),getSP(),getBP(),getCF());
        OutputDebugStringOem(demDebugBuffer);
    }
#endif
    return TRUE;
}
Example #2
0
VOID cmdReturnExitCode (VOID)
{
VDMINFO VDMInfo;
PREDIRCOMPLETE_INFO pRdrInfo;

    VDMInfo.VDMState = RETURN_ON_NO_COMMAND;
    VDMInfo.EnviornmentSize = 0;
    VDMInfo.ErrorCode = (ULONG)getDX();
    VDMInfo.CmdSize = 0;
    VDMInfo.TitleLen = 0;
    VDMInfo.ReservedLen = 0;
    VDMInfo.DesktopLen = 0;
    VDMInfo.CurDirectoryLen = 0;


    CntrlHandlerState = (CntrlHandlerState & ~CNTRL_SHELLCOUNT) |
                         (((WORD)(CntrlHandlerState & CNTRL_SHELLCOUNT))+1);

    nt_block_event_thread(0);
    fBlock = TRUE;

    // a dos program just terminate, inherit its current directories
    // and tell base too.
    cmdUpdateCurrentDirectories((BYTE)getAL());

    // Check for any copying needed for redirection
    pRdrInfo = (PREDIRCOMPLETE_INFO) (((ULONG)getBX() << 16) + (ULONG)getCX());

    if (cmdCheckCopyForRedirection (pRdrInfo) == FALSE)
            VDMInfo.ErrorCode = ERROR_NOT_ENOUGH_MEMORY;

    GetNextVDMCommand (&VDMInfo);
    if (VDMInfo.CmdSize > 0){
        setCF(1);
        IsRepeatCall = TRUE;
    }
    else {
        setCF(0);
        setAL((UCHAR)dwExitCode32);
        nt_resume_event_thread();
        nt_std_handle_notification(fSoftpcRedirectionOnShellOut);
        fBlock = FALSE;
    }

    CntrlHandlerState = (CntrlHandlerState & ~CNTRL_SHELLCOUNT) |
                         (((WORD)(CntrlHandlerState & CNTRL_SHELLCOUNT))-1);

    return;
}
Example #3
0
VOID demLockOper (VOID)
{
HANDLE	hFile;
DWORD	dwFileOffset,cbLock;

    // Collect all the parameters
    hFile = GETHANDLE(getBX(),getBP());
    dwFileOffset = GETULONG (getCX(),getDX());
    cbLock = GETULONG (getSI(),getDI());

    if(getAL() == 0){  // Locking case
	if (LockFile (hFile,
		      dwFileOffset,
		      0,
		      cbLock,
		      0
		     ) == TRUE) {
	    setCF (0);
	    return;
	}
    }
    else {
	if (UnlockFile (hFile,
			dwFileOffset,
			0,
			cbLock,
			0
		       ) == TRUE) {
	    setCF (0);
	    return;
	}
    }

    // Operation failed
    demClientError(hFile, (CHAR)-1);
    return;
}
Example #4
0
File: dem.c Project: GYGit/reactos
VOID BiosCharPrint(CHAR Character)
{
    /* Save AX and BX */
    USHORT AX = getAX();
    USHORT BX = getBX();

    /*
     * Set the parameters:
     * AL contains the character to print,
     * BL contains the character attribute,
     * BH contains the video page to use.
     */
    setAL(Character);
    setBL(DEFAULT_ATTRIBUTE);
    setBH(Bda->VideoPage);

    /* Call the BIOS INT 10h, AH=0Eh "Teletype Output" */
    setAH(0x0E);
    Int32Call(&DosContext, BIOS_VIDEO_INTERRUPT);

    /* Restore AX and BX */
    setBX(BX);
    setAX(AX);
}
Example #5
0
VOID cmdCheckBinary (VOID)
{

    LPSTR  lpAppName;
    ULONG  BinaryType;
    PPARAMBLOCK lpParamBlock;
    PCHAR  lpCommandTail,lpTemp;
    ULONG  AppNameLen,CommandTailLen = 0;
    USHORT CommandTailOff,CommandTailSeg,usTemp;
    NTSTATUS       Status;
    UNICODE_STRING Unicode;
    OEM_STRING     OemString;
    ANSI_STRING    AnsiString;


    if(DontCheckDosBinaryType){
        setCF(0);
        return;         // DOS Exe
    }

    lpAppName = (LPSTR) GetVDMAddr (getDS(),getDX());

    Unicode.Buffer = NULL;
    AnsiString.Buffer = NULL;
    RtlInitString((PSTRING)&OemString, lpAppName);
    Status = RtlOemStringToUnicodeString(&Unicode,&OemString,TRUE);
    if ( NT_SUCCESS(Status) ) {
        Status = RtlUnicodeStringToAnsiString(&AnsiString, &Unicode, TRUE);
        }
    if ( !NT_SUCCESS(Status) ) {
        Status = RtlNtStatusToDosError(Status);
        }
    else if (GetBinaryType (AnsiString.Buffer,(LPLONG)&BinaryType) == FALSE)
       {
        Status =  GetLastError();
        }

    if (Unicode.Buffer != NULL) {
        RtlFreeUnicodeString( &Unicode );
        }
    if (AnsiString.Buffer != NULL) {
        RtlFreeAnsiString( &AnsiString);
        }

    if (Status){
        setCF(1);
        setAX((USHORT)Status);
        return;         // Invalid path
    }


    if (BinaryType == SCS_DOS_BINARY) {
        setCF(0);
        return;         // DOS Exe
    }
                        // Prevent certain WOW apps from being spawned by DOS exe's
                        // This is for win31 compatibility
    else if (BinaryType == SCS_WOW_BINARY) {
        if (!IsWowAppRunnable(lpAppName)) {
            setCF(0);
            return;     // Run as DOS Exe
        }
    }


    if (VDMForWOW && BinaryType == SCS_WOW_BINARY && IsFirstWOWCheckBinary) {
        IsFirstWOWCheckBinary = FALSE;
        setCF(0);
        return;         // Special Hack for krnl286.exe
    }

    // dont allow running 32bit binaries from autoexec.nt. Reason is that
    // running non-dos binary requires that we should have read the actual
    // command from GetNextVDMCommand. Otherwise the whole design gets into
    // synchronization problems.

    if (IsFirstCall) {
        setCF(1);
        setAX((USHORT)ERROR_FILE_NOT_FOUND);
        return;
    }

    // Its a 32bit exe, replace the command with "command.com /z" and add the
    // original binary name to command tail.

    AppNameLen = strlen (lpAppName);

    lpParamBlock = (PPARAMBLOCK) GetVDMAddr (getES(),getBX());

    if (lpParamBlock) {
        CommandTailOff = FETCHWORD(lpParamBlock->OffCmdTail);
        CommandTailSeg = FETCHWORD(lpParamBlock->SegCmdTail);

        lpCommandTail = (PCHAR) GetVDMAddr (CommandTailSeg,CommandTailOff);

        if (lpCommandTail){
            CommandTailLen = *(PCHAR)lpCommandTail;
            lpCommandTail++;        // point to the actual command tail
            if (CommandTailLen)
                CommandTailLen++;   // For CR
        }

        // We are adding 3 below for "/z<space>" and anothre space between
        // AppName and CommandTail.

        if ((3 + AppNameLen + CommandTailLen ) > 128){
            setCF(1);
            setAX((USHORT)ERROR_NOT_ENOUGH_MEMORY);
            return;
        }
    }

    // copy the stub command.com name
    strcpy ((PCHAR)&pSCSInfo->SCS_ComSpec,lpszComSpec+8);
    lpTemp = (PCHAR) &pSCSInfo->SCS_ComSpec;
    lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0));
    usTemp = (USHORT)((ULONG)lpTemp >> 4);
    setDS(usTemp);
    usTemp = (USHORT)((ULONG)lpTemp & 0x0f);
    setDX((usTemp));

    // Form the command tail, first "3" is for "/z "
    pSCSInfo->SCS_CmdTail [0] = (UCHAR)(3 +
                                        AppNameLen +
                                        CommandTailLen);
    RtlCopyMemory ((PCHAR)&pSCSInfo->SCS_CmdTail[1],"/z ",3);
    strcpy ((PCHAR)&pSCSInfo->SCS_CmdTail[4],lpAppName);
    if (CommandTailLen) {
        pSCSInfo->SCS_CmdTail[4+AppNameLen] = ' ';
        RtlCopyMemory ((PCHAR)((ULONG)&pSCSInfo->SCS_CmdTail[4]+AppNameLen+1),
                lpCommandTail,
                CommandTailLen);
    }
    else {
        pSCSInfo->SCS_CmdTail[4+AppNameLen] = 0xd;
    }

    // Set the parameter Block
    if (lpParamBlock) {
        STOREWORD(pSCSInfo->SCS_ParamBlock.SegEnv,lpParamBlock->SegEnv);
        STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB1,lpParamBlock->pFCB1);
        STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB2,lpParamBlock->pFCB2);
    }
    else {
        STOREWORD(pSCSInfo->SCS_ParamBlock.SegEnv,0);
        STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB1,0);
        STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB2,0);
    }

    lpTemp = (PCHAR) &pSCSInfo->SCS_CmdTail;
    lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0));
    usTemp = (USHORT)((ULONG)lpTemp & 0x0f);
    STOREWORD(pSCSInfo->SCS_ParamBlock.OffCmdTail,usTemp);
    usTemp = (USHORT)((ULONG)lpTemp >> 4);
    STOREWORD(pSCSInfo->SCS_ParamBlock.SegCmdTail,usTemp);

    lpTemp = (PCHAR) &pSCSInfo->SCS_ParamBlock;
    lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0));
    usTemp = (USHORT)((ULONG)lpTemp >> 4);
    setES (usTemp);
    usTemp = (USHORT)((ULONG)lpTemp & 0x0f);
    setBX (usTemp);

    setCF(0);
    return;
}
Example #6
0
/*
   Entry point from Windows 386 Virtual Device Driver (INSIGNIA.386) - Provide
   virtualising services as required.
 */
GLOBAL void
virtual_device_trap IFN0()
   {
   int new_vb;

   switch ( getEAX() )
      {
   case VxD_Device_Init:
      /* We can check that the Intel version is valid */

      insignia_386_version = getDX();

      always_trace2("386 VxD: Device_Init version %d.%02d",
		    insignia_386_version / 100,
		    insignia_386_version % 100);

      /* pm selectors for virtualisation are in ebx and ecx */

      if ((getBX() !=0) && (getCX() !=0))
	sas_init_pm_selectors (getBX(), getCX());
      else
	always_trace0("386 VxD: Device_Init. Failed to get pm selectors!!");

      /* Compatibility test:
       * Return in top half of EDX the the "current" Intel version of the driver.
       * This allows an incompatible future driver to reject an old SoftWindows.
       */
#define INTEL_VERSION	102
      setEDX(INTEL_VERSION << 16);
      break;

   case VxD_Sys_VM_Init:
      always_trace0("386 VxD: Sys_VM_Init.");

      /* As safety measure undo anything which may be currently active */
      deallocate_all_NIDDB();
      restore_snapshot();

      /* Lock out Insignia Device Driver requests */
      allocation_allowed = FALSE;

      /* Form new instance */
      if ( allocate_NIDDB(getEBX(), &new_vb) )
	 {
	 /* Make new instance active (for create callback) */
	 swap_NIDDB(new_vb);

	 /* Copy instance data and action create callback */
	 copy_instance_data(vrecs[new_vb].vr_pinst_tbl, snapshot_ptrs);

	 /* Return virtualising byte to INSIGNIA.386 */
	 setEAX(new_vb);
	 }
      else
	 {
	 /* We can't do it */
	 setCF(1);   /* Inform Windows that Virtual Machine can't be created */
	 host_error(EG_MALLOC_FAILURE, ERR_CONT , "");
	 }
      break;

   case VxD_VM_Init:
      always_trace0("386 VxD: VM_Init.");
      /* Form new instance */
      if ( allocate_NIDDB(getEBX(), &new_vb) )
	 {
	 /* Make new instance active (for create callback) */
	 swap_NIDDB(new_vb);

	 /* Copy instance data and action create callback */
	 copy_instance_data(vrecs[new_vb].vr_pinst_tbl, snapshot_ptrs);

	 /* Return virtualising byte to INSIGNIA.386 */
	 setEAX(new_vb);
	 }
      else
	 {
	 /* We can't do it */
	 setCF(1);   /* Inform Windows that Virtual Machine can't be created */
	 host_error(EG_MALLOC_FAILURE, ERR_CONT , "");
	 }
      break;

   case VxD_VM_Not_Executeable:
      always_trace0("386 VxD: VM_Not_Executeable.");
      deallocate_specific_NIDDB(getEBX());
      break;

   case VxD_Device_Reboot_Notify:
      always_trace0("386 VxD: Device_Reboot_Notify.");
      deallocate_all_NIDDB();
      restore_snapshot();

      /* Clear our version number in case we are changing disks */
      insignia_386_version = 0;
      break;

   case VxD_System_Exit:
      always_trace0("386 VxD: System_Exit.");
      deallocate_all_NIDDB();
      restore_snapshot();
      ClearInstanceDataMarking();

#ifndef NTVDM
      host_mswin_disable();
#endif /* ! NTVDM */

      /* Clear our version number in case we are changing disks */
      insignia_386_version = 0;
      break;

   default:
      always_trace1("386 VxD: Unrecognised Control Message. 0x%02x", getEAX());
      }
   }
Example #7
0
static VOID WINAPI XmsBopProcedure(LPWORD Stack)
{
    switch (getAH())
    {
        /* Get XMS Version */
        case 0x00:
        {
            setAX(0x0300); /*    XMS version 3.00 */
            setBX(0x0301); /* Driver version 3.01 */
            setDX(0x0001); /* HMA present */
            break;
        }

        /* Request HMA */
        case 0x01:
        {
            /* Check whether HMA is already reserved */
            if (IsHmaReserved)
            {
                /* It is, bail out */
                setAX(0x0000);
                setBL(XMS_STATUS_HMA_IN_USE);
                break;
            }

            // NOTE: We implicitely suppose that we always have HMA.
            // If not, we should fail there with the XMS_STATUS_HMA_DOES_NOT_EXIST
            // error code.

            /* Check whether the requested size is above the minimal allowed one */
            if (getDX() < HmaMinSize)
            {
                /* It is not, bail out */
                setAX(0x0000);
                setBL(XMS_STATUS_HMA_MIN_SIZE);
                break;
            }

            /* Reserve it */
            IsHmaReserved = TRUE;
            setAX(0x0001);
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Release HMA */
        case 0x02:
        {
            /* Check whether HMA was reserved */
            if (!IsHmaReserved)
            {
                /* It was not, bail out */
                setAX(0x0000);
                setBL(XMS_STATUS_HMA_NOT_ALLOCATED);
                break;
            }

            /* Release it */
            IsHmaReserved = FALSE;
            setAX(0x0001);
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Global Enable A20 */
        case 0x03:
        {
            /* Enable A20 if needed */
            if (!IsA20Enabled)
            {
                XmsLocalEnableA20();
                if (getAX() != 0x0001)
                {
                    /* XmsLocalEnableA20 failed and already set AX and BL to their correct values */
                    break;
                }

                IsA20Enabled = TRUE;
            }

            setAX(0x0001); /* Line successfully enabled */
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Global Disable A20 */
        case 0x04:
        {
            UCHAR Result = XMS_STATUS_SUCCESS;

            /* Disable A20 if needed */
            if (IsA20Enabled)
            {
                XmsLocalDisableA20();
                if (getAX() != 0x0001)
                {
                    /* XmsLocalDisableA20 failed and already set AX and BL to their correct values */
                    break;
                }

                IsA20Enabled = FALSE;
                Result = getBL();
            }

            setAX(0x0001); /* Line successfully disabled */
            setBL(Result);
            break;
        }

        /* Local Enable A20 */
        case 0x05:
        {
            /* This call sets AX and BL to their correct values */
            XmsLocalEnableA20();
            break;
        }

        /* Local Disable A20 */
        case 0x06:
        {
            /* This call sets AX and BL to their correct values */
            XmsLocalDisableA20();
            break;
        }

        /* Query A20 State */
        case 0x07:
        {
            setAX(EmulatorGetA20());
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Query Free Extended Memory */
        case 0x08:
        {
            setAX(XmsGetLargestFreeBlock());
            setDX(FreeBlocks);

            if (FreeBlocks > 0)
                setBL(XMS_STATUS_SUCCESS);
            else
                setBL(XMS_STATUS_OUT_OF_MEMORY);

            break;
        }

        /* Allocate Extended Memory Block */
        case 0x09:
        {
            WORD Handle;
            UCHAR Result = XmsAlloc(getDX(), &Handle);

            if (Result == XMS_STATUS_SUCCESS)
            {
                setAX(1);
                setDX(Handle);
            }
            else
            {
                setAX(0);
                setBL(Result);
            }

            break;
        }

        /* Free Extended Memory Block */
        case 0x0A:
        {
            UCHAR Result = XmsFree(getDX());

            setAX(Result == XMS_STATUS_SUCCESS);
            setBL(Result);
            break;
        }

        /* Move Extended Memory Block */
        case 0x0B:
        {
            PVOID SourceAddress, DestAddress;
            PXMS_COPY_DATA CopyData = (PXMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI());
            PXMS_HANDLE HandleEntry;

            if (CopyData->SourceHandle)
            {
                HandleEntry = GetHandleRecord(CopyData->SourceHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAX(0);
                    setBL(XMS_STATUS_BAD_SRC_HANDLE);
                    break;
                }

                if (CopyData->SourceOffset >= HandleEntry->Size * XMS_BLOCK_SIZE)
                {
                    setAX(0);
                    setBL(XMS_STATUS_BAD_SRC_OFFSET);
                }

                SourceAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->SourceOffset);
            }
            else
            {
                /* The offset is actually a 16-bit segment:offset pointer */
                SourceAddress = FAR_POINTER(CopyData->SourceOffset);
            }

            if (CopyData->DestHandle)
            {
                HandleEntry = GetHandleRecord(CopyData->DestHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAX(0);
                    setBL(XMS_STATUS_BAD_DEST_HANDLE);
                    break;
                }

                if (CopyData->DestOffset >= HandleEntry->Size * XMS_BLOCK_SIZE)
                {
                    setAX(0);
                    setBL(XMS_STATUS_BAD_DEST_OFFSET);
                }

                DestAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->DestOffset);
            }
            else
            {
                /* The offset is actually a 16-bit segment:offset pointer */
                DestAddress = FAR_POINTER(CopyData->DestOffset);
            }

            /* Perform the move */
            RtlMoveMemory(DestAddress, SourceAddress, CopyData->Count);

            setAX(1);
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Lock Extended Memory Block */
        case 0x0C:
        {
            DWORD Address;
            UCHAR Result = XmsLock(getDX(), &Address);

            if (Result == XMS_STATUS_SUCCESS)
            {
                setAX(1);

                /* Store the LINEAR address in DX:BX */
                setDX(HIWORD(Address));
                setBX(LOWORD(Address));
            }
            else
            {
                setAX(0);
                setBL(Result);
            }

            break;
        }

        /* Unlock Extended Memory Block */
        case 0x0D:
        {
            UCHAR Result = XmsUnlock(getDX());

            setAX(Result == XMS_STATUS_SUCCESS);
            setBL(Result);
            break;
        }

        /* Get Handle Information */
        case 0x0E:
        {
            PXMS_HANDLE HandleEntry = GetHandleRecord(getDX());
            UINT i;
            UCHAR Handles = 0;

            if (!ValidateHandle(HandleEntry))
            {
                setAX(0);
                setBL(XMS_STATUS_INVALID_HANDLE);
                break;
            }

            for (i = 0; i < XMS_MAX_HANDLES; i++)
            {
                if (HandleTable[i].Handle == 0) Handles++;
            }

            setAX(1);
            setBH(HandleEntry->LockCount);
            setBL(Handles);
            setDX(HandleEntry->Size);
            break;
        }

        /* Reallocate Extended Memory Block */
        case 0x0F:
        {
            UCHAR Result = XmsRealloc(getDX(), getBX());

            setAX(Result == XMS_STATUS_SUCCESS);
            setBL(Result);
            break;
        }

        /* Request UMB */
        case 0x10:
        {
            BOOLEAN Result;
            USHORT Segment = 0x0000; /* No preferred segment  */
            USHORT Size = getDX();   /* Size is in paragraphs */

            Result = UmaDescReserve(&Segment, &Size);
            if (Result)
                setBX(Segment);
            else
                setBL(Size > 0 ? XMS_STATUS_SMALLER_UMB : XMS_STATUS_OUT_OF_UMBS);

            setDX(Size);
            setAX(Result);
            break;
        }

        /* Release UMB */
        case 0x11:
        {
            BOOLEAN Result;
            USHORT Segment = getDX();

            Result = UmaDescRelease(Segment);
            if (!Result)
                setBL(XMS_STATUS_INVALID_UMB);

            setAX(Result);
            break;
        }

        /* Reallocate UMB */
        case 0x12:
        {
            BOOLEAN Result;
            USHORT Segment = getDX();
            USHORT Size = getBX(); /* Size is in paragraphs */

            Result = UmaDescReallocate(Segment, &Size);
            if (!Result)
            {
                if (Size > 0)
                {
                    setBL(XMS_STATUS_SMALLER_UMB);
                    setDX(Size);
                }
                else
                {
                    setBL(XMS_STATUS_INVALID_UMB);
                }
            }

            setAX(Result);
            break;
        }

        default:
        {
            DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH());
            setBL(XMS_STATUS_NOT_IMPLEMENTED);
        }
    }
}
Example #8
0
VOID WINAPI ThirdPartyVDDBop(LPWORD Stack)
{
    /* Get the Function Number and skip it */
    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
    setIP(getIP() + 1);

    switch (FuncNum)
    {
        /* RegisterModule */
        case 0:
        {
            BOOL Success = TRUE;
            WORD RetVal  = 0;
            WORD Entry   = 0;
            LPCSTR DllName = NULL,
                   InitRoutineName     = NULL,
                   DispatchRoutineName = NULL;
            HMODULE hDll = NULL;
            VDD_PROC InitRoutine     = NULL,
                     DispatchRoutine = NULL;

            DPRINT("RegisterModule() called\n");

            /* Clear the Carry Flag (no error happened so far) */
            setCF(0);

            /* Retrieve the next free entry in the table (used later on) */
            Entry = GetNextFreeVDDEntry();
            if (Entry >= MAX_VDD_MODULES)
            {
                DPRINT1("Failed to create a new VDD module entry\n");
                Success = FALSE;
                RetVal = 4;
                goto Quit;
            }

            /* Retrieve the VDD name in DS:SI */
            DllName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getSI());

            /* Retrieve the initialization routine API name in ES:DI (optional --> ES=DI=0) */
            if (TO_LINEAR(getES(), getDI()) != 0)
                InitRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getES(), getDI());

            /* Retrieve the dispatch routine API name in DS:BX */
            DispatchRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getBX());

            DPRINT1("DllName = '%s' - InitRoutineName = '%s' - DispatchRoutineName = '%s'\n",
                    (DllName ? DllName : "n/a"),
                    (InitRoutineName ? InitRoutineName : "n/a"),
                    (DispatchRoutineName ? DispatchRoutineName : "n/a"));

            /* Load the VDD DLL */
            hDll = LoadLibraryA(DllName);
            if (hDll == NULL)
            {
                DWORD LastError = GetLastError();
                Success = FALSE;

                if (LastError == ERROR_NOT_ENOUGH_MEMORY)
                {
                    DPRINT1("Not enough memory to load DLL '%s'\n", DllName);
                    RetVal = 4;
                    goto Quit;
                }
                else
                {
                    DPRINT1("Failed to load DLL '%s'; last error = %d\n", DllName, LastError);
                    RetVal = 1;
                    goto Quit;
                }
            }

            /* Load the initialization routine if needed */
            if (InitRoutineName)
            {
                InitRoutine = (VDD_PROC)GetProcAddress(hDll, InitRoutineName);
                if (InitRoutine == NULL)
                {
                    DPRINT1("Failed to load the initialization routine '%s'\n", InitRoutineName);
                    Success = FALSE;
                    RetVal = 3;
                    goto Quit;
                }
            }

            /* Load the dispatch routine */
            DispatchRoutine = (VDD_PROC)GetProcAddress(hDll, DispatchRoutineName);
            if (DispatchRoutine == NULL)
            {
                DPRINT1("Failed to load the dispatch routine '%s'\n", DispatchRoutineName);
                Success = FALSE;
                RetVal = 2;
                goto Quit;
            }

            /* If we arrived there, that means everything is OK */

            /* Register the VDD DLL */
            VDDList[Entry].hDll = hDll;
            VDDList[Entry].DispatchRoutine = DispatchRoutine;

            /* Call the initialization routine if needed */
            if (InitRoutine) InitRoutine();

            /* We succeeded. RetVal will contain a valid VDD DLL handle */
            Success = TRUE;
            RetVal  = ENTRY_TO_HANDLE(Entry); // Convert the entry to a valid handle

Quit:
            if (!Success)
            {
                /* Unload the VDD DLL */
                if (hDll) FreeLibrary(hDll);

                /* Set the Carry Flag to indicate that an error happened */
                setCF(1);
            }
            // else
            // {
                // /* Clear the Carry Flag (success) */
                // setCF(0);
            // }
            setAX(RetVal);
            break;
        }

        /* UnRegisterModule */
        case 1:
        {
            WORD Handle = getAX();
            WORD Entry  = HANDLE_TO_ENTRY(Handle); // Convert the handle to a valid entry

            DPRINT("UnRegisterModule() called\n");

            /* Sanity checks */
            if (!IS_VALID_HANDLE(Handle) || VDDList[Entry].hDll == NULL)
            {
                DPRINT1("Invalid VDD DLL Handle: %d\n", Entry);
                /* Stop the VDM */
                EmulatorTerminate();
                return;
            }

            /* Unregister the VDD DLL */
            FreeLibrary(VDDList[Entry].hDll);
            VDDList[Entry].hDll = NULL;
            VDDList[Entry].DispatchRoutine = NULL;
            break;
        }

        /* DispatchCall */
        case 2:
        {
            WORD Handle = getAX();
            WORD Entry  = HANDLE_TO_ENTRY(Handle); // Convert the handle to a valid entry

            DPRINT("DispatchCall() called\n");

            /* Sanity checks */
            if (!IS_VALID_HANDLE(Handle)    ||
                VDDList[Entry].hDll == NULL ||
                VDDList[Entry].DispatchRoutine == NULL)
            {
                DPRINT1("Invalid VDD DLL Handle: %d\n", Entry);
                /* Stop the VDM */
                EmulatorTerminate();
                return;
            }

            /* Call the dispatch routine */
            VDDList[Entry].DispatchRoutine();
            break;
        }

        default:
        {
            DPRINT1("Unknown 3rd-party VDD BOP Function: 0x%02X\n", FuncNum);
            setCF(1);
            break;
        }
    }
}
Example #9
0
static VOID WINAPI EmsIntHandler(LPWORD Stack)
{
    switch (getAH())
    {
        /* Get Manager Status */
        case 0x40:
        {
            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Get Page Frame Segment */
        case 0x41:
        {
            setAH(EMS_STATUS_SUCCESS);
            setBX(EmsSegment);
            break;
        }

        /* Get Number of Unallocated Pages */
        case 0x42:
        {
            setAH(EMS_STATUS_SUCCESS);
            setBX(RtlNumberOfClearBits(&AllocBitmap));
            setDX(EmsTotalPages);
            break;
        }

        /* Get Handle and Allocate Memory */
        case 0x43:
        {
            USHORT Handle;
            UCHAR Status = EmsAlloc(getBX(), &Handle);

            if (Status == EMS_STATUS_SUCCESS)
                setDX(Handle);

            setAH(Status);
            break;
        }

        /* Map Memory */
        case 0x44:
        {
            setAH(EmsMap(getDX(), getAL(), getBX()));
            break;
        }

        /* Release Handle and Memory */
        case 0x45:
        {
            setAH(EmsFree(getDX()));
            break;
        }

        /* Get EMM Version */
        case 0x46:
        {
            setAH(EMS_STATUS_SUCCESS);
            setAL(EMS_VERSION_NUM);
            break;
        }

        /* Save Page Map */
        case 0x47:
        {
            // FIXME: This depends on an EMS handle given in DX
            RtlCopyMemory(MappingBackup, Mapping, sizeof(Mapping));
            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Restore Page Map */
        case 0x48:
        {
            // FIXME: This depends on an EMS handle given in DX
            RtlCopyMemory(Mapping, MappingBackup, sizeof(Mapping));
            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Get Number of Opened Handles */
        case 0x4B:
        {
            USHORT NumOpenHandles = 0;
            USHORT i;

            for (i = 0; i < ARRAYSIZE(HandleTable); i++)
            {
                if (HandleTable[i].Allocated)
                    ++NumOpenHandles;
            }

            setAH(EMS_STATUS_SUCCESS);
            setBX(NumOpenHandles);
            break;
        }

        /* Get Handle Number of Pages */
        case 0x4C:
        {
            PEMS_HANDLE HandleEntry = GetHandleRecord(getDX());

            if (!ValidateHandle(HandleEntry))
            {
                setAH(EMS_STATUS_INVALID_HANDLE);
                break;
            }

            setAH(EMS_STATUS_SUCCESS);
            setBX(HandleEntry->PageCount);
            break;
        }

        /* Get All Handles Number of Pages */
        case 0x4D:
        {
            PEMS_HANDLE_PAGE_INFO HandlePageInfo = (PEMS_HANDLE_PAGE_INFO)SEG_OFF_TO_PTR(getES(), getDI());
            USHORT NumOpenHandles = 0;
            USHORT i;

            for (i = 0; i < ARRAYSIZE(HandleTable); i++)
            {
                if (HandleTable[i].Allocated)
                {
                    HandlePageInfo->Handle = i;
                    HandlePageInfo->PageCount = HandleTable[i].PageCount;
                    ++HandlePageInfo;
                    ++NumOpenHandles;
                }
            }

            setAH(EMS_STATUS_SUCCESS);
            setBX(NumOpenHandles);
            break;
        }

        /* Get or Set Page Map */
        case 0x4E:
        {
            switch (getAL())
            {
                /* Get Mapping Registers  */
                // case 0x00: // TODO: NOT IMPLEMENTED
 
                /* Set Mapping Registers */
                // case 0x01: // TODO: NOT IMPLEMENTED

                /* Get and Set Mapping Registers At Once */
                // case 0x02: // TODO: NOT IMPLEMENTED

                /* Get Size of Page-Mapping Array */
                case 0x03:
                {
                    setAH(EMS_STATUS_SUCCESS);
                    setAL(sizeof(Mapping));
                    break;
                }

                default:
                {
                    DPRINT1("EMS function AH = 0x4E, subfunction AL = %02X NOT IMPLEMENTED\n", getAL());
                    setAH(EMS_STATUS_UNKNOWN_FUNCTION);
                    break;
                }
            }
            
            break;
        }

        /* Get/Set Handle Name */
        case 0x53:
        {
            PEMS_HANDLE HandleEntry = GetHandleRecord(getDX());

            if (!ValidateHandle(HandleEntry))
            {
                setAH(EMS_STATUS_INVALID_HANDLE);
                break;
            }

            if (getAL() == 0x00)
            {
                /* Retrieve the name */
                RtlCopyMemory(SEG_OFF_TO_PTR(getES(), getDI()),
                              HandleEntry->Name,
                              sizeof(HandleEntry->Name));
                setAH(EMS_STATUS_SUCCESS);
            }
            else if (getAL() == 0x01)
            {
                /* Store the name */
                RtlCopyMemory(HandleEntry->Name,
                              SEG_OFF_TO_PTR(getDS(), getSI()),
                              sizeof(HandleEntry->Name));
                setAH(EMS_STATUS_SUCCESS);
            }
            else
            {
                DPRINT1("Invalid subfunction %02X for EMS function AH = 53h\n", getAL());
                setAH(EMS_STATUS_INVALID_SUBFUNCTION);
            }

            break;
        }

        /* Handle Directory functions */
        case 0x54:
        {
            if (getAL() == 0x00)
            {
                /* Get Handle Directory */

                PEMS_HANDLE_DIR_ENTRY HandleDir = (PEMS_HANDLE_DIR_ENTRY)SEG_OFF_TO_PTR(getES(), getDI());
                USHORT NumOpenHandles = 0;
                USHORT i;

                for (i = 0; i < ARRAYSIZE(HandleTable); i++)
                {
                    if (HandleTable[i].Allocated)
                    {
                        HandleDir->Handle = i;
                        RtlCopyMemory(HandleDir->Name,
                                      HandleTable[i].Name,
                                      sizeof(HandleDir->Name));
                        ++HandleDir;
                        ++NumOpenHandles;
                    }
                }

                setAH(EMS_STATUS_SUCCESS);
                setAL((UCHAR)NumOpenHandles);
            }
            else if (getAL() == 0x01)
            {
                /* Search for Named Handle */

                PUCHAR HandleName = (PUCHAR)SEG_OFF_TO_PTR(getDS(), getSI());
                PEMS_HANDLE HandleFound = NULL;
                USHORT i;

                for (i = 0; i < ARRAYSIZE(HandleTable); i++)
                {
                    if (HandleTable[i].Allocated &&
                        RtlCompareMemory(HandleName,
                                         HandleTable[i].Name,
                                         sizeof(HandleTable[i].Name)) == sizeof(HandleTable[i].Name))
                    {
                        HandleFound = &HandleTable[i];
                        break;
                    }
                }

                /* Bail out if no handle was found */
                if (i >= ARRAYSIZE(HandleTable)) // HandleFound == NULL
                {
                    setAH(EMS_STATUS_HANDLE_NOT_FOUND);
                    break;
                }

                /* Return the handle number */
                setDX(i);

                /* Sanity check: Check whether the handle was unnamed */
                i = 0;
                while ((i < sizeof(HandleFound->Name)) && (HandleFound->Name[i] == '\0'))
                    ++i;

                if (i >= sizeof(HandleFound->Name))
                {
                    setAH(EMS_STATUS_UNNAMED_HANDLE);
                }
                else
                {
                    setAH(EMS_STATUS_SUCCESS);
                }
            }
            else if (getAL() == 0x02)
            {
                /*
                 * Get Total Number of Handles
                 *
                 * This function retrieves the maximum number of handles
                 * (allocated or not) the memory manager supports, which
                 * a program may request.
                 */
                setAH(EMS_STATUS_SUCCESS);
                setBX(ARRAYSIZE(HandleTable));
            }
            else
            {
                DPRINT1("Invalid subfunction %02X for EMS function AH = 54h\n", getAL());
                setAH(EMS_STATUS_INVALID_SUBFUNCTION);
            }

            break;
        }

        /* Move/Exchange Memory */
        case 0x57:
        {
            PUCHAR SourcePtr, DestPtr;
            PEMS_HANDLE HandleEntry;
            PEMS_PAGE PageEntry;
            BOOLEAN Exchange = getAL();
            PEMS_COPY_DATA Data = (PEMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI());

            if (Data->SourceType)
            {
                /* Expanded memory */
                HandleEntry = GetHandleRecord(Data->SourceHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAH(EMS_STATUS_INVALID_HANDLE);
                    break;
                }

                PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment);
                if (!PageEntry)
                {
                    setAH(EMS_STATUS_INV_LOGICAL_PAGE);
                    break;
                }

                SourcePtr = (PUCHAR)((ULONG_PTR)EmsMemory
                                     + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE
                                     + Data->SourceOffset);
            }
            else
            {
                /* Conventional memory */
                SourcePtr = (PUCHAR)SEG_OFF_TO_PTR(Data->SourceSegment, Data->SourceOffset);
            }

            if (Data->DestType)
            {
                /* Expanded memory */
                HandleEntry = GetHandleRecord(Data->DestHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAH(EMS_STATUS_INVALID_HANDLE);
                    break;
                }

                PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment);
                if (!PageEntry)
                {
                    setAH(EMS_STATUS_INV_LOGICAL_PAGE);
                    break;
                }

                DestPtr = (PUCHAR)((ULONG_PTR)EmsMemory
                                   + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE
                                   + Data->DestOffset);
            }
            else
            {
                /* Conventional memory */
                DestPtr = (PUCHAR)SEG_OFF_TO_PTR(Data->DestSegment, Data->DestOffset);
            }

            if (Exchange)
            {
                ULONG i;

                /* Exchange */
                for (i = 0; i < Data->RegionLength; i++)
                {
                    UCHAR Temp = DestPtr[i];
                    DestPtr[i] = SourcePtr[i];
                    SourcePtr[i] = Temp;
                }
            }
            else
            {
                /* Move */
                RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength);
            }

            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Get Mappable Physical Address Array */
        case 0x58:
        {
            if (getAL() == 0x00)
            {
                PEMS_MAPPABLE_PHYS_PAGE PageArray = (PEMS_MAPPABLE_PHYS_PAGE)SEG_OFF_TO_PTR(getES(), getDI());
                ULONG i;

                for (i = 0; i < EMS_PHYSICAL_PAGES; i++)
                {
                    PageArray->PageSegment = EMS_SEGMENT + i * (EMS_PAGE_SIZE >> 4);
                    PageArray->PageNumber  = i;
                    ++PageArray;
                }

                setAH(EMS_STATUS_SUCCESS);
                setCX(EMS_PHYSICAL_PAGES);
            }
            else if (getAL() == 0x01)
            {
                setAH(EMS_STATUS_SUCCESS);
                setCX(EMS_PHYSICAL_PAGES);
            }
            else
            {
                DPRINT1("Invalid subfunction %02X for EMS function AH = 58h\n", getAL());
                setAH(EMS_STATUS_INVALID_SUBFUNCTION);
            }

            break;
        }
Example #10
0
VOID
VDDDispatch(VOID)
{
    FUNCTIONCODE functioncode;
    CBM_FILE cbmfile;
    BOOLEAN error;

    FUNC_ENTER();

    functioncode = getDL();

    error = FALSE;

    // convert to BX value into a CBM_FILE
    switch (functioncode)
    {
    case FC_VDD_USLEEP:
    case FC_DRIVER_OPEN:
    case FC_GET_DRIVER_NAME:
        // FC_VDD_USLEEP, FC_DRIVER_OPEN and FC_GET_DRIVER_NAME are special,
        // they do not have a BX input.
        break;

    default:
        cbmfile = vdd_cbmfile_get(getBX());

        if (cbmfile == INVALID_HANDLE_VALUE)
        {
            DBG_ERROR((DBG_PREFIX "invalid BX given: %04x", getBX()));
            error = TRUE;
        }
        break;
    }

    if (!error)
    {
        switch (functioncode)
        {
        case FC_DRIVER_OPEN:     error = vdd_driver_open();          break;
        case FC_DRIVER_CLOSE:    error = vdd_driver_close(cbmfile);  break;
        case FC_LISTEN:          error = vdd_listen(cbmfile);        break;
        case FC_TALK:            error = vdd_talk(cbmfile);          break;
        case FC_OPEN:            error = vdd_open(cbmfile);          break;
        case FC_CLOSE:           error = vdd_close(cbmfile);         break;
        case FC_RAW_READ:        error = vdd_raw_read(cbmfile);      break;
        case FC_RAW_WRITE:       error = vdd_raw_write(cbmfile);     break;
        case FC_UNLISTEN:        error = vdd_unlisten(cbmfile);      break;
        case FC_UNTALK:          error = vdd_untalk(cbmfile);        break;
        case FC_GET_EOI:         error = vdd_get_eoi(cbmfile);       break;
        case FC_CLEAR_EOI:       error = vdd_clear_eoi(cbmfile);     break;
        case FC_RESET:           error = vdd_reset(cbmfile);         break;
        case FC_PP_READ:         error = vdd_pp_read(cbmfile);       break;
        case FC_PP_WRITE:        error = vdd_pp_write(cbmfile);      break;
        case FC_IEC_POLL:        error = vdd_iec_poll(cbmfile);      break;
        case FC_IEC_GET:         error = vdd_iec_get(cbmfile);       break;
        case FC_IEC_SET:         error = vdd_iec_set(cbmfile);       break;
        case FC_IEC_RELEASE:     error = vdd_iec_release(cbmfile);   break;
        case FC_IEC_SETRELEASE:  error = vdd_iec_setrelease(cbmfile); break;
        case FC_IEC_WAIT:        error = vdd_iec_wait(cbmfile);      break;
        case FC_UPLOAD:          error = vdd_upload(cbmfile);        break;
        case FC_DEVICE_STATUS:   error = vdd_device_status(cbmfile); break; 
        case FC_EXEC_COMMAND:    error = vdd_exec_command(cbmfile);  break;
        case FC_IDENTIFY:        error = vdd_identify(cbmfile);      break;
        case FC_IDENTIFY_XP1541: error = vdd_identify_xp1541(cbmfile); break;
        case FC_GET_DRIVER_NAME: error = vdd_get_driver_name();      break;

        case FC_VDD_USLEEP:      error = vdd_usleep();               break;

        case FC_VDD_INSTALL_IOHOOK:   error = vdd_install_iohook(cbmfile);   break;
        case FC_VDD_UNINSTALL_IOHOOK: error = vdd_uninstall_iohook(cbmfile); break;

        default:
            // this function is not implemented:
            DBG_ERROR((DBG_PREFIX "unknown function code in DL: %02x", functioncode));
            error = TRUE;
            break;
        }
    }

    setCF(error ? 1 : 0);

    FUNC_LEAVE();
}
Example #11
0
void ISV_RegisterModule (BOOL fMode)
{
    char *pchDll,*pchInit,*pchDispatch;
    HANDLE hDll;
    FARPROC DispatchEntry;
    FARPROC InitEntry;
    ULONG i;
    UCHAR uchMode;

    // Check if we have free space in bop table.
    for (i=0; i<MAX_ISV_BOP; i++) {
    if (isvbop_table[i].hDll == 0)
        break;
    }

    if (i == MAX_ISV_BOP) {
    setCF (1);
    setAX(4);
    return;
    }

    uchMode = fMode ? TRUE : FALSE;

    pchDll = (PCHAR) Sim32GetVDMPointer (SEGOFF(getDS(),getSI()),
                                         1,
                                         uchMode
                                         );
    if (pchDll == NULL) {
    setCF (1);
    setAX(1);
    return;
    }
    pchInit = (PCHAR) Sim32GetVDMPointer(SEGOFF(getES(),getDI()),
                                         1,
                                         uchMode
                                         );

    pchDispatch = (PCHAR) Sim32GetVDMPointer(SEGOFF(getDS(),getBX()),
                                             1,
                                             uchMode
                                             );
    if (pchDispatch == NULL) {
    setCF (1);
    setAX(2);
    return;
    }

    if ((hDll = SafeLoadLibrary(pchDll)) == NULL){
    setCF (1);
    setAX(1);
    return;
    }

    // Get the init entry point and dispatch entry point
    if (pchInit){
    if ((ULONG)pchInit < 64*1024){
        if (strlen (pchInit) >= MAX_PROC_NAME) {
        FreeLibrary(hDll);
        setCF (1);
        setAX(4);
        return;
        }
        strcpy (procbuffer,pchInit);
        pchInit = procbuffer;
    }

    if ((InitEntry = (MYFARPROC)GetProcAddress(hDll, pchInit)) == NULL){
        FreeLibrary(hDll);
        setCF(1);
        setAX(3);
            return;
    }
    }

    if ((ULONG)pchDispatch < 64*1024){
    if (strlen (pchDispatch) >= MAX_PROC_NAME) {
        FreeLibrary(hDll);
        setCF (1);
        setAX(4);
        return;
    }
    strcpy (procbuffer,pchDispatch);
    pchDispatch = procbuffer;
    }

    if ((DispatchEntry = (MYFARPROC)GetProcAddress(hDll, pchDispatch)) == NULL){
    FreeLibrary(hDll);
    setCF(1);
    setAX(2);
    return;
    }

    // Call the init routine
    if (pchInit) {
    (*InitEntry)();
    }

    // Fill up the bop table
    isvbop_table[i].hDll = hDll;
    isvbop_table[i].fpDispatch = DispatchEntry;

    i++;

    setAX((USHORT)i);

    return;
}