mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
895 lines
15 KiB
895 lines
15 KiB
/*++
|
|
|
|
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);
|
|
}
|