896 lines
15 KiB
C
896 lines
15 KiB
C
/*++
|
||
|
||
Copyright (c) 1990-1995 Microsoft Corporation
|
||
|
||
|
||
Module Name:
|
||
|
||
handle.c
|
||
|
||
|
||
Abstract:
|
||
|
||
This module contains all function which deal with handle table for the
|
||
common UI
|
||
|
||
|
||
Author:
|
||
|
||
30-Jan-1996 Tue 16:28:56 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
[Environment:]
|
||
|
||
NT Windows - Common Printer Driver UI DLL
|
||
|
||
|
||
[Notes:]
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
|
||
|
||
#include "precomp.h"
|
||
#pragma hdrstop
|
||
|
||
|
||
#define DBG_CPSUIFILENAME DbgHandle
|
||
|
||
|
||
#define DBG_CPSUI_HTABLE 0x00000001
|
||
#define DBG_FINDHANDLE 0x00000002
|
||
#define DBG_ADD_DATA 0x00000004
|
||
#define DBG_HANDLE_DESTROY 0x00000008
|
||
#define DBG_GET_HPSPINFO 0x00000010
|
||
#define DBG_SEM 0x00000020
|
||
|
||
DEFINE_DBGVAR(0);
|
||
|
||
|
||
HANDLE hCPSUIMutex = NULL;
|
||
CPSUIHANDLETABLE CPSUIHandleTable = { NULL, 0, 0, 0, 0 };
|
||
extern DWORD TlsIndex;
|
||
|
||
|
||
|
||
|
||
BOOL
|
||
LOCK_CPSUI_HANDLETABLE(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function get the lock the object
|
||
|
||
|
||
Arguments:
|
||
|
||
VOID
|
||
|
||
Return Value:
|
||
|
||
BOOL
|
||
|
||
|
||
Author:
|
||
|
||
27-Mar-1996 Wed 11:27:26 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Ok = FALSE;
|
||
|
||
|
||
if (hCPSUIMutex) {
|
||
|
||
WORD Idx;
|
||
|
||
switch (WaitForSingleObject(hCPSUIMutex, MAX_SEM_WAIT)) {
|
||
|
||
case WAIT_OBJECT_0:
|
||
|
||
//
|
||
// Signaled, and own it now
|
||
//
|
||
|
||
if (!CPSUIHandleTable.cWait++) {
|
||
|
||
CPSUIHandleTable.ThreadID = GetCurrentThreadId();
|
||
}
|
||
|
||
Idx = TLSVALUE_2_IDX(TlsGetValue(TlsIndex));
|
||
|
||
TlsSetValue(TlsIndex,
|
||
ULongToPtr(MK_TLSVALUE(CPSUIHandleTable.cWait, Idx)));
|
||
|
||
CPSUIDBG(DBG_SEM, ("LOCK_CPSUI_HANDLETABLE: ThreadID=%ld, cWait=%ld",
|
||
GetCurrentThreadId(), CPSUIHandleTable.cWait));
|
||
|
||
Ok = TRUE;
|
||
|
||
break;
|
||
|
||
case WAIT_ABANDONED:
|
||
|
||
CPSUIERR(("LockCPSUIObject()= WAIT_ABANDONED"));
|
||
break;
|
||
|
||
case WAIT_TIMEOUT:
|
||
|
||
CPSUIERR(("LockCPSUIObject()= WAIT_TIMEOUT"));
|
||
break;
|
||
|
||
default:
|
||
|
||
CPSUIERR(("LockCPSUIObject()= UNKNOWN"));
|
||
break;
|
||
}
|
||
}
|
||
|
||
return(Ok);
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
UNLOCK_CPSUI_HANDLETABLE(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
|
||
|
||
Return Value:
|
||
|
||
|
||
|
||
|
||
Author:
|
||
|
||
27-Mar-1996 Wed 11:39:37 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Ok = FALSE;
|
||
|
||
|
||
if (hCPSUIMutex) {
|
||
|
||
DWORD ThreadID = GetCurrentThreadId();
|
||
WORD Idx;
|
||
|
||
|
||
CPSUIDBG(DBG_SEM, ("UNLOCK_CPSUI_HANDLETABLE: ThreadID=%ld, cWait=%ld",
|
||
ThreadID, CPSUIHandleTable.cWait));
|
||
|
||
if (ThreadID == CPSUIHandleTable.ThreadID) {
|
||
|
||
if (CPSUIHandleTable.cWait) {
|
||
|
||
if (--CPSUIHandleTable.cWait == 0) {
|
||
|
||
CPSUIHandleTable.ThreadID = NO_THREADID;
|
||
}
|
||
|
||
|
||
Idx = TLSVALUE_2_IDX(TlsGetValue(TlsIndex));
|
||
|
||
TlsSetValue(TlsIndex,
|
||
ULongToPtr(MK_TLSVALUE(CPSUIHandleTable.cWait, Idx)));
|
||
|
||
ReleaseMutex(hCPSUIMutex);
|
||
Ok = TRUE;
|
||
|
||
} else {
|
||
|
||
CPSUIERR(("The Thread ID does not match=%ld",
|
||
CPSUIHandleTable.ThreadID));
|
||
}
|
||
|
||
} else {
|
||
|
||
CPSUIERR(("The ThreadID=%ld does not own the mutex", ThreadID));
|
||
}
|
||
}
|
||
|
||
return(Ok);
|
||
}
|
||
|
||
|
||
|
||
|
||
PCPSUIPAGE
|
||
HANDLETABLE_GetCPSUIPage(
|
||
HANDLE hTable
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function take a handle table and return the pData assoicated with it,
|
||
the pData must already added by HANDLETABLE_AddCPSUIPage()
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
|
||
|
||
Return Value:
|
||
|
||
pCPSUIPage, NULL if FAILED
|
||
|
||
|
||
Author:
|
||
|
||
28-Dec-1995 Thu 17:05:11 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
PDATATABLE pDataTable;
|
||
PCPSUIPAGE pFoundPage = NULL;
|
||
PCPSUIPAGE pCPSUIPage;
|
||
WORD Idx;
|
||
|
||
|
||
LOCK_CPSUI_HANDLETABLE();
|
||
|
||
if ((hTable) &&
|
||
(pDataTable = CPSUIHandleTable.pDataTable) &&
|
||
(HANDLE_2_PREFIX(hTable) == HANDLE_TABLE_PREFIX) &&
|
||
((Idx = HANDLE_2_IDX(hTable)) < CPSUIHandleTable.MaxCount) &&
|
||
(pCPSUIPage = pDataTable[Idx].pCPSUIPage)) {
|
||
|
||
if (pCPSUIPage->ID != CPSUIPAGE_ID) {
|
||
|
||
CPSUIERR(("HANDLETABLE_FindpCPSUIPage(%08lx), pCPSUIPage=%08lx INVALID Internal ID",
|
||
hTable, pCPSUIPage));
|
||
|
||
} else if (pCPSUIPage->hCPSUIPage != hTable) {
|
||
|
||
CPSUIERR(("HANDLETABLE_FIndpCPSUIPage(%08lx), pCPSUIPagePage=%08lx, HANDLE not matched",
|
||
hTable, pCPSUIPage));
|
||
|
||
} else {
|
||
|
||
pCPSUIPage->cLock++;
|
||
pFoundPage = pCPSUIPage;
|
||
}
|
||
}
|
||
|
||
UNLOCK_CPSUI_HANDLETABLE();
|
||
|
||
return(pFoundPage);
|
||
}
|
||
|
||
|
||
|
||
DWORD
|
||
HANDLETABLE_LockCPSUIPage(
|
||
PCPSUIPAGE pCPSUIPage
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function decrement the cLock for the Page currently in USE
|
||
|
||
|
||
Arguments:
|
||
|
||
pCPSUIPage - Pointer to the CPSUIPAGE
|
||
|
||
|
||
Return Value:
|
||
|
||
BOOL, true if decrment successfully
|
||
|
||
|
||
Author:
|
||
|
||
05-Apr-1996 Fri 16:41:46 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD cLock = 0;
|
||
|
||
|
||
if (pCPSUIPage) {
|
||
|
||
LOCK_CPSUI_HANDLETABLE();
|
||
|
||
cLock = ++(pCPSUIPage->cLock);
|
||
|
||
UNLOCK_CPSUI_HANDLETABLE();
|
||
}
|
||
|
||
return(cLock);
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
HANDLETABLE_UnGetCPSUIPage(
|
||
PCPSUIPAGE pCPSUIPage
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function decrement the cLock for the Page currently in USE
|
||
|
||
|
||
Arguments:
|
||
|
||
pCPSUIPage - Pointer to the CPSUIPAGE
|
||
|
||
|
||
Return Value:
|
||
|
||
BOOL, true if decrment successfully
|
||
|
||
|
||
Author:
|
||
|
||
05-Apr-1996 Fri 16:41:46 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Ok;
|
||
|
||
|
||
if (pCPSUIPage) {
|
||
|
||
LOCK_CPSUI_HANDLETABLE();
|
||
|
||
if (Ok = (BOOL)pCPSUIPage->cLock) {
|
||
|
||
--(pCPSUIPage->cLock);
|
||
|
||
} else {
|
||
|
||
CPSUIERR(("HANDLETABLE_UnlockpCPSUIPage(%08lx), cLock is ZERO",
|
||
pCPSUIPage));
|
||
}
|
||
|
||
UNLOCK_CPSUI_HANDLETABLE();
|
||
|
||
} else {
|
||
|
||
Ok = FALSE;
|
||
}
|
||
|
||
return(Ok);
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
HANDLETABLE_IsChildPage(
|
||
PCPSUIPAGE pChildPage,
|
||
PCPSUIPAGE pParentPage
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function check if pChildPage is one of the pParentPage's child or
|
||
its decedent child
|
||
|
||
|
||
Arguments:
|
||
|
||
pChildPage - Pointer to the CPSUIPAGE for child
|
||
|
||
pParentPage - Pointer to the CPSUIPAGE for parent to be checked
|
||
|
||
Return Value:
|
||
|
||
TRUE, if this is child, otherwise FALSE
|
||
|
||
|
||
Author:
|
||
|
||
08-Apr-1996 Mon 12:52:51 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Ok = FALSE;
|
||
|
||
|
||
LOCK_CPSUI_HANDLETABLE();
|
||
|
||
|
||
if (pChildPage) {
|
||
|
||
while (pChildPage->pParent) {
|
||
|
||
if (pChildPage->pParent == pParentPage) {
|
||
|
||
Ok = TRUE;
|
||
break;
|
||
|
||
} else {
|
||
|
||
pChildPage = pChildPage->pParent;
|
||
}
|
||
}
|
||
}
|
||
|
||
UNLOCK_CPSUI_HANDLETABLE();
|
||
|
||
return(Ok);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
PCPSUIPAGE
|
||
HANDLETABLE_GetRootPage(
|
||
PCPSUIPAGE pCPSUIPage
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function find the root page for pCPSUIPage
|
||
|
||
Arguments:
|
||
|
||
pCPSUIPage - Pointer to the CPSUIPAGE who's root page to be searched
|
||
|
||
|
||
Return Value:
|
||
|
||
PCPSUIPAGE - Pointer to root page, NULL if failed
|
||
|
||
|
||
Author:
|
||
|
||
08-Apr-1996 Mon 12:49:42 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
PCPSUIPAGE pPage;
|
||
PCPSUIPAGE pRootPage = NULL;
|
||
|
||
|
||
LOCK_CPSUI_HANDLETABLE();
|
||
|
||
|
||
pPage = pCPSUIPage;
|
||
|
||
//
|
||
// If we need to search for the root page, then try it now
|
||
//
|
||
|
||
while ((pPage) && (pPage->pParent)) {
|
||
|
||
pPage = pPage->pParent;
|
||
}
|
||
|
||
if ((pPage) && (pPage->Flags & CPF_ROOT)) {
|
||
|
||
pPage->cLock++;
|
||
pRootPage = pPage;
|
||
|
||
} else {
|
||
|
||
CPSUIERR(("HANDLETABLE_FindpRootPage(%08lx): No ROOT Page found",
|
||
pCPSUIPage));
|
||
}
|
||
|
||
UNLOCK_CPSUI_HANDLETABLE();
|
||
|
||
return(pRootPage);
|
||
}
|
||
|
||
|
||
|
||
|
||
HANDLE
|
||
HANDLETABLE_AddCPSUIPage(
|
||
PCPSUIPAGE pCPSUIPage
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function add pData to the handle table, if new
|
||
|
||
|
||
Arguments:
|
||
|
||
pCPSUIPage - Pointer to the CPSUIPAGE to be add to the handle table
|
||
|
||
|
||
Return Value:
|
||
|
||
HANDLE, if NULL then it failed, the handle already exists
|
||
|
||
|
||
Author:
|
||
|
||
28-Dec-1995 Thu 16:03:25 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
HANDLE hTable;
|
||
PDATATABLE pDataTable;
|
||
|
||
|
||
LOCK_CPSUI_HANDLETABLE();
|
||
|
||
if ((!CPSUIHandleTable.pDataTable) ||
|
||
(CPSUIHandleTable.CurCount >= CPSUIHandleTable.MaxCount)) {
|
||
|
||
if (!CPSUIHandleTable.pDataTable) {
|
||
|
||
CPSUIHandleTable.CurCount =
|
||
CPSUIHandleTable.MaxCount = 0;
|
||
}
|
||
|
||
CPSUIDBG(DBG_ADD_DATA,
|
||
("HANDLETABLE_AddCPSUIPage(%08lx): Table reach LIMIT, Expanded=%ld->%ld",
|
||
CPSUIHandleTable.pDataTable,
|
||
CPSUIHandleTable.CurCount,
|
||
CPSUIHandleTable.CurCount + DATATABLE_BLK_COUNT));
|
||
|
||
//
|
||
// Reallocate Table
|
||
//
|
||
|
||
if ((CPSUIHandleTable.MaxCount <= DATATABLE_MAX_COUNT) &&
|
||
(pDataTable = LocalAlloc(LPTR,
|
||
(CPSUIHandleTable.MaxCount +
|
||
DATATABLE_BLK_COUNT) *
|
||
sizeof(DATATABLE)))) {
|
||
|
||
if (CPSUIHandleTable.pDataTable) {
|
||
|
||
CopyMemory(pDataTable,
|
||
CPSUIHandleTable.pDataTable,
|
||
CPSUIHandleTable.MaxCount * sizeof(DATATABLE));
|
||
|
||
LocalFree((HLOCAL)CPSUIHandleTable.pDataTable);
|
||
}
|
||
|
||
CPSUIHandleTable.pDataTable = pDataTable;
|
||
CPSUIHandleTable.MaxCount += DATATABLE_BLK_COUNT;
|
||
|
||
} else {
|
||
|
||
CPSUIERR(("HANDLETABLE_AddCPSUIPage(): Expand TABLE failed"));
|
||
}
|
||
}
|
||
|
||
hTable = NULL;
|
||
|
||
if (pDataTable = CPSUIHandleTable.pDataTable) {
|
||
|
||
WORD Idx;
|
||
|
||
for (Idx = 0; Idx < CPSUIHandleTable.MaxCount; Idx++, pDataTable++) {
|
||
|
||
if (!pDataTable->pCPSUIPage) {
|
||
|
||
hTable = WORD_2_HANDLE(Idx);
|
||
pDataTable->pCPSUIPage = pCPSUIPage;
|
||
pCPSUIPage->cLock = 1;
|
||
|
||
CPSUIHandleTable.CurCount++;
|
||
|
||
CPSUIDBG(DBG_ADD_DATA, ("HANDLETABLE_AddCPSUIPage(%08lx): Idx=%ld, Cur=%ld, Max=%ld",
|
||
pCPSUIPage, Idx,
|
||
CPSUIHandleTable.CurCount,
|
||
CPSUIHandleTable.MaxCount));
|
||
|
||
break;
|
||
|
||
} else if (pDataTable->pCPSUIPage == pCPSUIPage) {
|
||
|
||
CPSUIERR(("HANDLETABLE_AddCPSUIPage(%08lx): pCPSUIPage exists, Idx=%ld",
|
||
pCPSUIPage, Idx));
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!hTable) {
|
||
|
||
CPSUIERR(("HANDLETABLE_AddCPSUIPage(%08lx:%ld) Cannot find empty entry",
|
||
CPSUIHandleTable.pDataTable,
|
||
CPSUIHandleTable.MaxCount));
|
||
}
|
||
|
||
UNLOCK_CPSUI_HANDLETABLE();
|
||
|
||
return(hTable);
|
||
}
|
||
|
||
|
||
|
||
|
||
BOOL
|
||
HANDLETABLE_DeleteHandle(
|
||
HANDLE hTable
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function delete a handle from the handle table
|
||
|
||
|
||
Arguments:
|
||
|
||
hTable - Handle to the handle table to be deleted
|
||
|
||
|
||
Return Value:
|
||
|
||
BOOL
|
||
|
||
|
||
Author:
|
||
|
||
28-Dec-1995 Thu 17:42:42 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
PDATATABLE pDataTable;
|
||
PCPSUIPAGE pCPSUIPage;
|
||
WORD Idx;
|
||
BOOL Ok = FALSE;
|
||
|
||
|
||
LOCK_CPSUI_HANDLETABLE();
|
||
|
||
if ((pDataTable = CPSUIHandleTable.pDataTable) &&
|
||
(HANDLE_2_PREFIX(hTable) == HANDLE_TABLE_PREFIX) &&
|
||
(CPSUIHandleTable.CurCount) &&
|
||
((Idx = HANDLE_2_IDX(hTable)) < CPSUIHandleTable.MaxCount) &&
|
||
(pCPSUIPage = (pDataTable += Idx)->pCPSUIPage)) {
|
||
|
||
if (pCPSUIPage->cLock) {
|
||
|
||
CPSUIERR(("HANDLETABLE_DeleteHandle(%08lx), pCPSUIPage=%08lx, cLock=%ld",
|
||
hTable, pCPSUIPage, pCPSUIPage->cLock));
|
||
|
||
} else {
|
||
|
||
// check to release the activation context (if any)
|
||
if (pCPSUIPage->hActCtx && pCPSUIPage->hActCtx != INVALID_HANDLE_VALUE) {
|
||
|
||
ReleaseActCtx(pCPSUIPage->hActCtx);
|
||
pCPSUIPage->hActCtx = INVALID_HANDLE_VALUE;
|
||
}
|
||
|
||
pDataTable->pCPSUIPage = NULL;
|
||
Ok = TRUE;
|
||
|
||
//
|
||
// Reduce current count and free the memory
|
||
//
|
||
|
||
CPSUIHandleTable.CurCount--;
|
||
|
||
LocalFree((HLOCAL)pCPSUIPage);
|
||
}
|
||
|
||
} else {
|
||
|
||
CPSUIERR(("HANDLETABLE_DeleteHandle(%08lx) not found, Idx=%ld, pDataTable=%08lx",
|
||
hTable, Idx, pDataTable));
|
||
}
|
||
|
||
UNLOCK_CPSUI_HANDLETABLE();
|
||
|
||
return(Ok);
|
||
}
|
||
|
||
|
||
|
||
|
||
BOOL
|
||
HANDLETABLE_Create(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
|
||
|
||
Return Value:
|
||
|
||
|
||
|
||
|
||
Author:
|
||
|
||
28-Dec-1995 Thu 16:46:27 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
CPSUIHandleTable.pDataTable = NULL;
|
||
CPSUIHandleTable.MaxCount =
|
||
CPSUIHandleTable.CurCount = 0;
|
||
CPSUIHandleTable.ThreadID = NO_THREADID;
|
||
CPSUIHandleTable.cWait = 0;
|
||
|
||
if (hCPSUIMutex = CreateMutex(NULL, FALSE, NULL)) {
|
||
|
||
CPSUIDBG(DBG_CPSUI_HTABLE, ("CREATE: CreateMutex=%08lx", hCPSUIMutex));
|
||
|
||
return(TRUE);
|
||
|
||
} else {
|
||
|
||
CPSUIERR(("CreateMutex() FAILED, Exit"));
|
||
return(FALSE);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
HANDLETABLE_Destroy(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
|
||
|
||
Return Value:
|
||
|
||
|
||
|
||
|
||
Author:
|
||
|
||
28-Dec-1995 Thu 16:48:32 created -by- Daniel Chou (danielc)
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
PDATATABLE pDataTable;
|
||
WORD Idx;
|
||
|
||
LOCK_CPSUI_HANDLETABLE();
|
||
|
||
if (hCPSUIMutex) {
|
||
|
||
if (pDataTable = CPSUIHandleTable.pDataTable) {
|
||
|
||
for (Idx = 0;
|
||
Idx < CPSUIHandleTable.MaxCount;
|
||
Idx++, pDataTable++) {
|
||
|
||
if (pDataTable->pCPSUIPage) {
|
||
|
||
CPSUIERR(("HANDLETABLE_Destroy: Idx=%ld, pPage=%08lx, cLock=%ld is not delete yet",
|
||
Idx, pDataTable->pCPSUIPage, pDataTable->pCPSUIPage->cLock));
|
||
|
||
LocalFree((HLOCAL)pDataTable->pCPSUIPage);
|
||
|
||
pDataTable->pCPSUIPage = NULL;
|
||
|
||
if (CPSUIHandleTable.CurCount) {
|
||
|
||
--(CPSUIHandleTable.CurCount);
|
||
|
||
} else {
|
||
|
||
CPSUIERR(("HANDLETABLE_Destroy(): Unmatched CurCount"));
|
||
}
|
||
}
|
||
}
|
||
|
||
LocalFree((HLOCAL)CPSUIHandleTable.pDataTable);
|
||
|
||
CPSUIHandleTable.pDataTable = NULL;
|
||
CPSUIHandleTable.MaxCount =
|
||
CPSUIHandleTable.CurCount = 0;
|
||
}
|
||
}
|
||
|
||
UNLOCK_CPSUI_HANDLETABLE();
|
||
|
||
CloseHandle(hCPSUIMutex);
|
||
}
|