mirror of
https://github.com/WindowsNT351/CE-Collections.git
synced 2025-12-27 01:20:25 +08:00
420 lines
8.0 KiB
C
420 lines
8.0 KiB
C
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
//
|
|
// Use of this sample source code is subject to the terms of the Microsoft
|
|
// license agreement under which you licensed this sample source code. If
|
|
// you did not accept the terms of the license agreement, you are not
|
|
// authorized to use this sample source code. For the terms of the license,
|
|
// please see the license agreement between you and Microsoft or, if applicable,
|
|
// see the LICENSE.RTF on your install media or the root of your tools installation.
|
|
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
|
|
//
|
|
/*++
|
|
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
PARTICULAR PURPOSE.
|
|
|
|
Module Name:
|
|
|
|
Abstract:
|
|
|
|
Functions:
|
|
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
#include "xmsapi.h"
|
|
|
|
#pragma warning(disable:4704)
|
|
|
|
#pragma pack(1)
|
|
|
|
typedef struct _EXTENDED_MEMORY_MOVE
|
|
{
|
|
unsigned long ulLength;
|
|
unsigned int uiSourceHandle;
|
|
unsigned long ulSourceOffset;
|
|
unsigned int uiDestinationHandle;
|
|
unsigned long ulDestinationOffset;
|
|
|
|
} EXTENDED_MEMORY_MOVE, *PEXTENDED_MEMORY_MOVE;
|
|
|
|
#pragma pack()
|
|
|
|
int (far * XMSControl)() = 0;
|
|
|
|
struct
|
|
{
|
|
int iErrorCode;
|
|
char * pszErrorString;
|
|
}
|
|
XmsErrorMessages[] =
|
|
{
|
|
{ XMS_SUCCESS, "Success" },
|
|
|
|
{ XMS_E_NOT_IMPLEMENTED, "Not implemented" },
|
|
{ XMS_E_VDISK_DETECTED, "VDISK detected" },
|
|
{ XMS_E_A20_ERROR, "A20 error" },
|
|
|
|
{ XMS_W_NO_HMA, "No HMA" },
|
|
{ XMS_W_HMA_IN_USE, "HMA in use" },
|
|
{ XMS_W_HMA_DENIED, "HMA denied" },
|
|
{ XMS_W_HMA_NOT_ALLOCATED, "HMA not allocated" },
|
|
{ XMS_W_A20_STILL_ENABLED, "A20 still enabled" },
|
|
|
|
{ XMS_S_NO_FREE_EXTENDED_MEMORY, "No free extended memory" },
|
|
{ XMS_S_NO_FREE_HANDLES, "No free handles" },
|
|
{ XMS_S_INVALID_HANDLE, "Invalid handle" },
|
|
{ XMS_S_INVALID_SOURCE_HANDLE, "Invalid source handle" },
|
|
{ XMS_S_INVALID_SOURCE_OFFSET, "Invalid source offset" },
|
|
{ XMS_S_INVALID_DESTINATION_HANDLE, "Invalid destination handle" },
|
|
{ XMS_S_INVALID_DESTINATION_OFFSET, "Invalid destination offset" },
|
|
{ XMS_S_INVALID_LENGTH, "Invalid length" },
|
|
{ XMS_S_INVALID_OVERLAP, "Invalid overlap" },
|
|
{ XMS_S_PARITY_ERROR, "Parity error" },
|
|
{ XMS_S_BLOCK_LOCKED, "Block locked" },
|
|
{ XMS_S_HANDLE_LOCKED, "Handle locked" },
|
|
{ XMS_S_LOCK_COUNT_OVERFLOW, "Lock count overflow" },
|
|
{ XMS_S_LOCK_FAILED, "Lock failed" },
|
|
|
|
{ XMS_I_SMALLER_UMB_AVAILABLE, "Smaller UMB available" },
|
|
{ XMS_I_NO_UMBS_AVAILABLE, "No UMBs available" },
|
|
{ XMS_I_INVALID_UMB_SEGMENT, "Invalid UMB segment" }
|
|
};
|
|
|
|
#define N_XMS_ERROR_MESSAGES (sizeof(XmsErrorMessages) / sizeof(XmsErrorMessages[0]))
|
|
|
|
int
|
|
XmsIsInstalled()
|
|
{
|
|
int bInstalled = 0;
|
|
|
|
if (XMSControl != 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
_asm
|
|
{
|
|
mov ax,4300h ; Check if XMS is present)
|
|
int 2Fh
|
|
xor ah,ah
|
|
cmp al,80h
|
|
jne done ; Nope - no point in continuing
|
|
|
|
mov ax,4310h ; Get XMS entry point
|
|
int 2Fh
|
|
mov WORD PTR [XMSControl], bx ; Save entry point
|
|
mov WORD PTR [XMSControl + 2], es
|
|
|
|
inc bInstalled ; Indicate installed
|
|
}
|
|
|
|
done:
|
|
return bInstalled;
|
|
}
|
|
|
|
int
|
|
XmsLocalEnableA20()
|
|
{
|
|
int xmsError = XMS_SUCCESS;
|
|
|
|
if (!XmsIsInstalled())
|
|
{
|
|
return XMS_E_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
_asm
|
|
{
|
|
mov ah, 05h
|
|
call [XMSControl]
|
|
clc
|
|
rcr al, 1
|
|
jc done
|
|
|
|
xor bh, bh
|
|
mov xmsError, bx
|
|
}
|
|
|
|
done:
|
|
return xmsError;
|
|
}
|
|
|
|
int
|
|
XmsLocalDisableA20()
|
|
{
|
|
int xmsError = XMS_SUCCESS;
|
|
|
|
if (!XmsIsInstalled())
|
|
{
|
|
return XMS_E_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
_asm
|
|
{
|
|
mov ah, 06h
|
|
call [XMSControl]
|
|
clc
|
|
rcr al, 1
|
|
jc done
|
|
|
|
xor bh, bh
|
|
mov xmsError, bx
|
|
}
|
|
|
|
done:
|
|
return xmsError;
|
|
}
|
|
|
|
int
|
|
XmsQueryA20(
|
|
int *pbEnabled)
|
|
{
|
|
int xmsError = XMS_SUCCESS;
|
|
|
|
if (!XmsIsInstalled())
|
|
{
|
|
return XMS_E_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
_asm
|
|
{
|
|
mov ah, 07h
|
|
call [XMSControl]
|
|
|
|
push si
|
|
mov si, pbEnabled
|
|
mov WORD PTR [si], ax
|
|
pop si
|
|
|
|
xor bh, bh
|
|
mov xmsError, bx
|
|
}
|
|
|
|
return xmsError;
|
|
}
|
|
|
|
int
|
|
XmsQueryFreeExtendedMemory(
|
|
unsigned int *puiLargestFreeBlock,
|
|
unsigned int *puiTotalFree)
|
|
{
|
|
int xmsError = XMS_SUCCESS;
|
|
|
|
if (!XmsIsInstalled())
|
|
{
|
|
return XMS_E_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
_asm
|
|
{
|
|
mov ah, 08h
|
|
call [XMSControl]
|
|
|
|
push si
|
|
mov si, puiLargestFreeBlock
|
|
mov WORD PTR [si], ax
|
|
|
|
mov si, puiTotalFree
|
|
mov WORD PTR [si], dx
|
|
pop si
|
|
|
|
xor bh, bh
|
|
mov xmsError, bx
|
|
}
|
|
|
|
return xmsError;
|
|
}
|
|
|
|
int
|
|
XmsAllocateExtendedMemory(
|
|
unsigned int uiBlockSizeK,
|
|
unsigned int * puiBlockHandle)
|
|
{
|
|
int xmsError = XMS_SUCCESS;
|
|
|
|
if (!XmsIsInstalled())
|
|
{
|
|
return XMS_E_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
_asm
|
|
{
|
|
mov ah, 09h
|
|
mov dx, uiBlockSizeK
|
|
call [XMSControl]
|
|
|
|
push si
|
|
mov si, puiBlockHandle
|
|
mov WORD PTR [si], dx
|
|
pop si
|
|
|
|
clc
|
|
rcr al, 1
|
|
jc done
|
|
|
|
xor bh, bh
|
|
mov xmsError, bx
|
|
}
|
|
|
|
done:
|
|
return xmsError;
|
|
}
|
|
|
|
int
|
|
XmsFreeExtendedMemory(
|
|
unsigned int uiBlockHandle)
|
|
{
|
|
int xmsError = XMS_SUCCESS;
|
|
|
|
if (!XmsIsInstalled())
|
|
{
|
|
return XMS_E_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
_asm
|
|
{
|
|
mov ah, 0Ah
|
|
mov dx, uiBlockHandle
|
|
call [XMSControl]
|
|
|
|
clc
|
|
rcr al, 1
|
|
jc done
|
|
|
|
xor bh, bh
|
|
mov xmsError, bx
|
|
}
|
|
|
|
done:
|
|
return xmsError;
|
|
}
|
|
|
|
int
|
|
XmsMoveExtendedMemory(
|
|
unsigned int uiSourceHandle,
|
|
unsigned long ulSourceOffset,
|
|
unsigned int uiDestinationHandle,
|
|
unsigned long ulDestinationOffset,
|
|
unsigned long ulLength)
|
|
{
|
|
EXTENDED_MEMORY_MOVE moveInfo;
|
|
|
|
int xmsError = XMS_SUCCESS;
|
|
|
|
if (!XmsIsInstalled())
|
|
{
|
|
return XMS_E_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
moveInfo.uiSourceHandle = uiSourceHandle;
|
|
moveInfo.ulSourceOffset = ulSourceOffset;
|
|
moveInfo.uiDestinationHandle = uiDestinationHandle;
|
|
moveInfo.ulDestinationOffset = ulDestinationOffset;
|
|
moveInfo.ulLength = ulLength;
|
|
|
|
_asm
|
|
{
|
|
mov ah, 0Bh
|
|
|
|
push si
|
|
lea si, moveInfo
|
|
call [XMSControl]
|
|
pop si
|
|
|
|
clc
|
|
rcr al, 1
|
|
jc done
|
|
|
|
xor bh, bh
|
|
mov xmsError, bx
|
|
}
|
|
|
|
done:
|
|
return xmsError;
|
|
}
|
|
|
|
int
|
|
XmsLockExtendedMemory(
|
|
unsigned int uiBlockHandle,
|
|
unsigned long * pulLinearAddress)
|
|
{
|
|
int xmsError = XMS_SUCCESS;
|
|
|
|
if (!XmsIsInstalled())
|
|
{
|
|
return XMS_E_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
_asm
|
|
{
|
|
mov ah, 0Ch
|
|
mov dx, uiBlockHandle
|
|
call [XMSControl]
|
|
|
|
push si
|
|
mov si, pulLinearAddress
|
|
mov WORD PTR [si], bx
|
|
mov WORD PTR [si + 2], dx
|
|
pop si
|
|
|
|
clc
|
|
rcr al, 1
|
|
jc done
|
|
|
|
xor bh, bh
|
|
mov xmsError, bx
|
|
}
|
|
|
|
done:
|
|
return xmsError;
|
|
}
|
|
|
|
int
|
|
XmsUnlockExtendedMemory(
|
|
unsigned int uiBlockHandle)
|
|
{
|
|
int xmsError = XMS_SUCCESS;
|
|
|
|
if (!XmsIsInstalled())
|
|
{
|
|
return XMS_E_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
_asm
|
|
{
|
|
mov ah, 0Dh
|
|
mov dx, uiBlockHandle
|
|
call [XMSControl]
|
|
|
|
clc
|
|
rcr al, 1
|
|
jc done
|
|
|
|
xor bh, bh
|
|
mov xmsError, bx
|
|
}
|
|
|
|
done:
|
|
return xmsError;
|
|
}
|
|
|
|
char *XmsErrorString(int xmsError)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < N_XMS_ERROR_MESSAGES; i++)
|
|
{
|
|
if (XmsErrorMessages[i].iErrorCode == xmsError)
|
|
{
|
|
return XmsErrorMessages[i].pszErrorString;
|
|
}
|
|
}
|
|
|
|
return "Unknown error";
|
|
}
|