windows-nt/Source/XPSP1/NT/printscan/ui/compstui/handle.c
2020-09-26 16:20:57 +08:00

896 lines
15 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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);
}