mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[DXG] Implement DdAllocateObject, DdFreeObject, DdGetFreeHandle, DdHmgAlloc, DdHmgFree CORE-4490
svn path=/trunk/; revision=74143
This commit is contained in:
parent
c6af963e8d
commit
0b0e9bd364
3 changed files with 264 additions and 30 deletions
|
@ -11,13 +11,14 @@
|
|||
#include <dxg_int.h>
|
||||
|
||||
/* The DdHmgr manger stuff */
|
||||
ULONG gcSizeDdHmgr = 64 * sizeof(DD_ENTRY);
|
||||
ULONG gcSizeDdHmgr = 1024;
|
||||
PDD_ENTRY gpentDdHmgr = NULL;
|
||||
|
||||
ULONG gcMaxDdHmgr = 0;
|
||||
PDD_ENTRY gpentDdHmgrLast = NULL;
|
||||
|
||||
HANDLE ghFreeDdHmgr = 0;
|
||||
/* next free ddhmg handle number available to reuse */
|
||||
ULONG ghFreeDdHmgr = 0;
|
||||
HSEMAPHORE ghsemHmgr = NULL;
|
||||
|
||||
BOOL
|
||||
|
@ -25,7 +26,7 @@ FASTCALL
|
|||
VerifyObjectOwner(PDD_ENTRY pEntry)
|
||||
{
|
||||
DWORD Pid = (DWORD)(DWORD_PTR)PsGetCurrentProcessId() & 0xFFFFFFFC;
|
||||
DWORD check = pEntry->ObjectOwner.ulObj & 0xFFFFFFFE;
|
||||
DWORD check = (DWORD)pEntry->Pid & 0xFFFFFFFE;
|
||||
return ( (check == Pid) || (!check));
|
||||
}
|
||||
|
||||
|
@ -46,7 +47,7 @@ BOOL
|
|||
FASTCALL
|
||||
DdHmgCreate(VOID)
|
||||
{
|
||||
gpentDdHmgr = EngAllocMem(FL_ZERO_MEMORY, gcSizeDdHmgr, TAG_THDD);
|
||||
gpentDdHmgr = EngAllocMem(FL_ZERO_MEMORY, gcSizeDdHmgr * sizeof(DD_ENTRY), TAG_THDD);
|
||||
ghFreeDdHmgr = 0;
|
||||
gcMaxDdHmgr = 1;
|
||||
|
||||
|
@ -144,8 +145,8 @@ PVOID
|
|||
FASTCALL
|
||||
DdHmgLock(HANDLE DdHandle, UCHAR ObjectType, BOOLEAN LockOwned)
|
||||
{
|
||||
DWORD Index = DDHMG_HTOI(DdHandle);
|
||||
|
||||
DWORD Index = (DWORD)(DWORD_PTR)DdHandle & 0x1FFFFF;
|
||||
PDD_ENTRY pEntry = NULL;
|
||||
PVOID Object = NULL;
|
||||
|
||||
|
@ -157,19 +158,17 @@ DdHmgLock(HANDLE DdHandle, UCHAR ObjectType, BOOLEAN LockOwned)
|
|||
if ( Index < gcMaxDdHmgr )
|
||||
{
|
||||
pEntry = (PDD_ENTRY)((PBYTE)gpentDdHmgr + (sizeof(DD_ENTRY) * Index));
|
||||
|
||||
if ( VerifyObjectOwner(pEntry) )
|
||||
{
|
||||
/* FIXME
|
||||
if ( (pEntry->Objt == ObjectType ) &&
|
||||
(pEntry->FullUnique == (((DWORD)DdHandle >> 21) & 0x7FF) ) &&
|
||||
(pEntry->pobj->cExclusiveLock == 0) &&
|
||||
(pEntry->pobj->Tid == PsGetCurrentThread()))
|
||||
{
|
||||
InterlockedIncrement(&pEntry->pobj->cExclusiveLock);
|
||||
pEntry->pobj->Tid = PsGetCurrentThread();
|
||||
Object = pEntry->pobj;
|
||||
}
|
||||
*/
|
||||
if ( ( pEntry->Objt == ObjectType ) &&
|
||||
( pEntry->FullUnique == (((ULONG)DdHandle >> 21) & 0x7FF) ) &&
|
||||
( !pEntry->pobj->cExclusiveLock ) )
|
||||
{
|
||||
InterlockedIncrement((VOID*)&pEntry->pobj->cExclusiveLock);
|
||||
pEntry->pobj->Tid = KeGetCurrentThread();
|
||||
Object = pEntry->pobj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,3 +179,244 @@ DdHmgLock(HANDLE DdHandle, UCHAR ObjectType, BOOLEAN LockOwned)
|
|||
|
||||
return Object;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name DdAllocateObject
|
||||
* @implemented
|
||||
*
|
||||
* The function DdAllocateObject is used internally in dxg.sys
|
||||
* It allocates memory for a DX kernel object
|
||||
*
|
||||
* @param UINT32 oSize
|
||||
* Size of memory to be allocated
|
||||
* @param UCHAR oType
|
||||
* Object type
|
||||
* @param BOOLEAN oZeroMemory
|
||||
* Zero memory
|
||||
*
|
||||
* @remarks.
|
||||
* Only used internally in dxg.sys
|
||||
*/
|
||||
PVOID
|
||||
FASTCALL
|
||||
DdAllocateObject(ULONG objSize, UCHAR objType, BOOLEAN objZeroMemory)
|
||||
{
|
||||
PVOID pObject = NULL;
|
||||
|
||||
if (objZeroMemory)
|
||||
pObject = EngAllocMem(FL_ZERO_MEMORY, objSize, ((ULONG)objType << 24) + TAG_DH_0);
|
||||
else
|
||||
pObject = EngAllocMem(0, objSize, ((ULONG)objType << 24) + TAG_DH_0);
|
||||
|
||||
if (!pObject)
|
||||
{
|
||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
|
||||
return pObject;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name DdFreeObject
|
||||
* @implemented
|
||||
*
|
||||
* The function DdFreeObject is used internally in dxg.sys
|
||||
* It frees memory of DX kernel object
|
||||
*
|
||||
* @param PVOID pObject
|
||||
* Object memory to be freed
|
||||
*
|
||||
* @remarks.
|
||||
* Only used internally in dxg.sys
|
||||
*/
|
||||
VOID
|
||||
FASTCALL
|
||||
DdFreeObject(PVOID pObject)
|
||||
{
|
||||
EngFreeMem(pObject);
|
||||
}
|
||||
|
||||
|
||||
/*++
|
||||
* @name DdGetFreeHandle
|
||||
* @implemented
|
||||
*
|
||||
* The function DdGetFreeHandle is used internally in dxg.sys
|
||||
* It allocates new handle for specified object type
|
||||
*
|
||||
* @param UCHAR oType
|
||||
* Object type
|
||||
*
|
||||
* @return
|
||||
* Returns handle or 0 if it fails.
|
||||
*
|
||||
* @remarks.
|
||||
* Only used internally in dxg.sys
|
||||
*--*/
|
||||
HANDLE
|
||||
FASTCALL
|
||||
DdGetFreeHandle(UCHAR objType)
|
||||
{
|
||||
PVOID mAllocMem = NULL;
|
||||
ULONG mAllocEntries = 0;
|
||||
PDD_ENTRY pEntry = NULL;
|
||||
ULONG retVal;
|
||||
ULONG index;
|
||||
|
||||
// check if memory is allocated
|
||||
if (!gpentDdHmgr)
|
||||
return 0;
|
||||
|
||||
// check if we reached maximum handle index
|
||||
if (gcMaxDdHmgr == DDHMG_HANDLE_LIMIT)
|
||||
return 0;
|
||||
|
||||
// check if we have free handle to reuse
|
||||
if (ghFreeDdHmgr)
|
||||
{
|
||||
index = ghFreeDdHmgr;
|
||||
pEntry = (PDD_ENTRY)((PLONG)gpentDdHmgr + (sizeof(DD_ENTRY) * index));
|
||||
|
||||
// put next free index to our global variable
|
||||
ghFreeDdHmgr = pEntry->NextFree;
|
||||
|
||||
// build handle
|
||||
pEntry->FullUnique = objType | 8;
|
||||
retVal = (pEntry->FullUnique << 21) | index;
|
||||
return (HANDLE)retVal;
|
||||
}
|
||||
|
||||
// if all pre-allocated memory is already used then allocate more
|
||||
if (gcSizeDdHmgr == gcMaxDdHmgr)
|
||||
{
|
||||
// allocate buffer for next 1024 handles
|
||||
mAllocEntries = gcSizeDdHmgr + 1024;
|
||||
mAllocMem = EngAllocMem(FL_ZERO_MEMORY, sizeof(DD_ENTRY) * (mAllocEntries), TAG_THDD);
|
||||
if (!mAllocMem)
|
||||
return 0;
|
||||
|
||||
memmove(&mAllocMem, gpentDdHmgr, sizeof(DD_ENTRY) * gcSizeDdHmgr);
|
||||
gcSizeDdHmgr = mAllocEntries;
|
||||
gpentDdHmgrLast = gpentDdHmgr;
|
||||
EngFreeMem(gpentDdHmgr);
|
||||
gpentDdHmgr = mAllocMem;
|
||||
}
|
||||
|
||||
pEntry = (PDD_ENTRY)((PLONG)gpentDdHmgr + (sizeof(DD_ENTRY) * gcMaxDdHmgr));
|
||||
|
||||
// build handle
|
||||
pEntry->FullUnique = objType | 8;
|
||||
retVal = (pEntry->FullUnique << 21) | gcMaxDdHmgr;
|
||||
gcMaxDdHmgr = gcMaxDdHmgr + 1;
|
||||
|
||||
return (HANDLE)retVal;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name DdHmgAlloc
|
||||
* @implemented
|
||||
*
|
||||
* The function DdHmgAlloc is used internally in dxg.sys
|
||||
* It allocates object
|
||||
*
|
||||
* @param ULONG objSize
|
||||
* Size of memory to be allocated
|
||||
* @param CHAR objType
|
||||
* Object type
|
||||
* @param UINT objFlags
|
||||
* Object flags
|
||||
*
|
||||
* @return
|
||||
* Handle if object is not locked by objFlags
|
||||
* Object if lock is set in objFlags
|
||||
* 0 if it fails.
|
||||
*
|
||||
* @remarks.
|
||||
* Only used internally in dxg.sys
|
||||
*--*/
|
||||
HANDLE
|
||||
FASTCALL
|
||||
DdHmgAlloc(ULONG objSize, CHAR objType, UINT objFlags)
|
||||
{
|
||||
PVOID pObject = NULL;
|
||||
HANDLE DdHandle = NULL;
|
||||
PDD_ENTRY pEntry = NULL;
|
||||
DWORD Index;
|
||||
|
||||
pObject = DdAllocateObject(objSize, objType, TRUE);
|
||||
if (!pObject)
|
||||
return 0;
|
||||
|
||||
EngAcquireSemaphore(ghsemHmgr);
|
||||
|
||||
/* Get next free handle */
|
||||
DdHandle = DdGetFreeHandle(objType);
|
||||
|
||||
if (DdHandle)
|
||||
{
|
||||
Index = DDHMG_HTOI(DdHandle);
|
||||
|
||||
pEntry = (PDD_ENTRY)((PLONG)gpentDdHmgr + (sizeof(DD_ENTRY) * Index));
|
||||
|
||||
pEntry->pobj = pObject;
|
||||
pEntry->Objt = objType;
|
||||
|
||||
pEntry->Pid = (HANDLE)(((ULONG)PsGetCurrentProcessId() & 0xFFFFFFFC) | ((ULONG)(pEntry->Pid) & 1));
|
||||
|
||||
if (objFlags & 1)
|
||||
pEntry->pobj->Tid = KeGetCurrentThread();
|
||||
|
||||
pEntry->pobj->cExclusiveLock = objFlags & 1;
|
||||
pEntry->pobj->hHmgr = DdHandle;
|
||||
|
||||
EngReleaseSemaphore(ghsemHmgr);
|
||||
|
||||
/* Return handle if object not locked */
|
||||
if (!(objFlags & 1))
|
||||
return DdHandle;
|
||||
|
||||
return (HANDLE)pEntry;
|
||||
}
|
||||
|
||||
EngReleaseSemaphore(ghsemHmgr);
|
||||
DdFreeObject(pObject);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name DdHmgFree
|
||||
* @implemented
|
||||
*
|
||||
* The function DdHmgFree is used internally in dxg.sys
|
||||
* It frees DX object and memory allocated to it
|
||||
*
|
||||
* @param HANDLE DdHandle
|
||||
* DX object handle
|
||||
*
|
||||
* @remarks.
|
||||
* Only used internally in dxg.sys
|
||||
*--*/
|
||||
VOID
|
||||
FASTCALL
|
||||
DdHmgFree(HANDLE DdHandle)
|
||||
{
|
||||
PDD_ENTRY pEntry = NULL;
|
||||
|
||||
DWORD Index = DDHMG_HTOI(DdHandle);
|
||||
|
||||
EngAcquireSemaphore(ghsemHmgr);
|
||||
|
||||
pEntry = (PDD_ENTRY)((PLONG)gpentDdHmgr + (sizeof(DD_ENTRY) * Index));
|
||||
|
||||
// check if we have object that should be freed
|
||||
if (pEntry->pobj)
|
||||
DdFreeObject(pEntry->pobj);
|
||||
|
||||
pEntry->NextFree = ghFreeDdHmgr;
|
||||
|
||||
// reset process ID
|
||||
pEntry->Pid = (HANDLE)((DWORD)pEntry->Pid & 1);
|
||||
ghFreeDdHmgr = Index;
|
||||
|
||||
EngReleaseSemaphore(ghsemHmgr);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#define INTERNAL_CALL NTAPI
|
||||
#define NT_BUILD_ENVIRONMENT
|
||||
|
||||
#define DDHMG_HANDLE_LIMIT 0x200000
|
||||
#define DDHMG_HTOI(DdHandle) ((DWORD)DdHandle & (DDHMG_HANDLE_LIMIT-1))
|
||||
|
||||
|
||||
#include <windef.h>
|
||||
#include <winerror.h>
|
||||
#include <wingdi.h>
|
||||
|
@ -45,22 +49,11 @@ typedef struct _DD_BASEOBJECT
|
|||
union
|
||||
{
|
||||
PDD_BASEOBJECT pobj;
|
||||
HANDLE hFree;
|
||||
ULONG NextFree;
|
||||
};
|
||||
union
|
||||
{
|
||||
ULONG ulObj;
|
||||
struct
|
||||
{
|
||||
USHORT Count;
|
||||
USHORT Lock;
|
||||
HANDLE Pid;
|
||||
};
|
||||
} ObjectOwner;
|
||||
HANDLE Pid;
|
||||
USHORT FullUnique;
|
||||
UCHAR Objt;
|
||||
UCHAR Flags;
|
||||
PVOID pUser;
|
||||
} DD_ENTRY, *PDD_ENTRY;
|
||||
|
||||
typedef struct _EDD_SURFACE_LOCAL
|
||||
|
@ -80,7 +73,7 @@ extern ULONG gcSizeDdHmgr;
|
|||
extern PDD_ENTRY gpentDdHmgr;
|
||||
extern ULONG gcMaxDdHmgr;
|
||||
extern PDD_ENTRY gpentDdHmgrLast;
|
||||
extern HANDLE ghFreeDdHmgr;
|
||||
extern ULONG ghFreeDdHmgr;
|
||||
extern HSEMAPHORE ghsemHmgr;
|
||||
extern LONG gcDummyPageRefCnt;
|
||||
extern HSEMAPHORE ghsemDummyPage;
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
#define TAG_THDD 'ddht'
|
||||
#define TAG_GINI 'iniG'
|
||||
#define TAG_DH_0 '0 hD'
|
||||
|
|
Loading…
Reference in a new issue