Leaked source code of windows server 2003
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.
 
 
 
 
 
 

421 lines
11 KiB

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
handle.c
Abstract:
This module contains the handle table mgmt routines.
Author:
Wesley Witt (wesw) 12-Nov-1996
Revision History:
--*/
#include "faxsvc.h"
#pragma hdrstop
LIST_ENTRY g_HandleTableListHead;
CFaxCriticalSection g_CsHandleTable;
void
FreeServiceContextHandles(
void
)
{
PLIST_ENTRY Next;
PHANDLE_ENTRY pHandleEntry;
Next = g_HandleTableListHead.Flink;
while ((ULONG_PTR)Next != (ULONG_PTR)&g_HandleTableListHead)
{
pHandleEntry = CONTAINING_RECORD( Next, HANDLE_ENTRY, ListEntry );
Next = pHandleEntry->ListEntry.Flink;
CloseFaxHandle (pHandleEntry);
}
return;
}
static
PHANDLE_ENTRY
CreateNewHandle(
handle_t hBinding,
FaxHandleType Type,
DWORD dwClientAPIVersion, // Used for connection handles
PLINE_INFO LineInfo, // Used for port handles
DWORD Flags // Used for port handles
)
{
PHANDLE_ENTRY pHandleEntry;
pHandleEntry = (PHANDLE_ENTRY) MemAlloc( sizeof(HANDLE_ENTRY) );
if (!pHandleEntry)
{
return NULL;
}
ZeroMemory (pHandleEntry, sizeof(HANDLE_ENTRY));
pHandleEntry->hBinding = hBinding;
pHandleEntry->Type = Type;
pHandleEntry->dwClientAPIVersion = dwClientAPIVersion;
pHandleEntry->LineInfo = LineInfo;
pHandleEntry->Flags = Flags;
pHandleEntry->bReleased = FALSE;
pHandleEntry->hFile = INVALID_HANDLE_VALUE;
EnterCriticalSection( &g_CsHandleTable );
InsertTailList( &g_HandleTableListHead, &pHandleEntry->ListEntry );
LeaveCriticalSection( &g_CsHandleTable );
return pHandleEntry;
}
PHANDLE_ENTRY
CreateNewConnectionHandle(
handle_t hBinding,
DWORD dwClientAPIVersion
)
{
return CreateNewHandle(
hBinding,
FHT_SERVICE,
dwClientAPIVersion,
NULL, // Unused
0 // Unused
);
}
PHANDLE_ENTRY
CreateNewPortHandle(
handle_t hBinding,
PLINE_INFO LineInfo,
DWORD Flags
)
{
return CreateNewHandle(
hBinding,
FHT_PORT,
0, // Unused
LineInfo,
Flags
);
}
PHANDLE_ENTRY
CreateNewMsgEnumHandle(
handle_t hBinding,
HANDLE hFileFind,
LPCWSTR lpcwstrFirstFileName,
FAX_ENUM_MESSAGE_FOLDER Folder
)
/*++
Routine name : CreateNewMsgEnumHandle
Routine description:
Creates a new context handle for messages enumeration
Author:
Eran Yariv (EranY), Dec, 1999
Arguments:
hBinding [in] - RPC Binding handle
hFileFind [in] - Find file handle
lpcwstrFirstFileName [in] - Name of first file found
Folder [in] - Archive folder type of find file search
Return Value:
Returns a pointer to a newly created handle
--*/
{
DEBUG_FUNCTION_NAME(TEXT("CreateNewMsgEnumHandle"));
Assert (INVALID_HANDLE_VALUE != hFileFind);
if (MAX_PATH <= lstrlen (lpcwstrFirstFileName))
{
DebugPrintEx(
DEBUG_ERR,
TEXT("String passed is too long (%s)"),
lpcwstrFirstFileName);
ASSERT_FALSE;
return NULL;
}
PHANDLE_ENTRY pHandle = CreateNewHandle (hBinding,
FHT_MSGENUM,
FindClientAPIVersion(hBinding), // Client API version
NULL, // Unused
0); // Unused
if (!pHandle)
{
DebugPrintEx(
DEBUG_ERR,
TEXT("CreateNewHandle failed"));
return NULL;
}
//
// Store find file handle and first file in the new context
//
pHandle->hFile = hFileFind;
wcsncpy (pHandle->wstrFileName, lpcwstrFirstFileName, ARR_SIZE(pHandle->wstrFileName)-1);
pHandle->Folder = Folder;
return pHandle;
} // CreateNewMsgEnumHandle
PHANDLE_ENTRY
CreateNewCopyHandle(
handle_t hBinding,
HANDLE hFile,
BOOL bCopyToServer,
LPCWSTR lpcwstrFileName,
PJOB_QUEUE pJobQueue
)
/*++
Routine name : CreateNewCopyHandle
Routine description:
Creates a new context handle for RPC copy
Author:
Eran Yariv (EranY), Dec, 1999
Arguments:
hBinding [in] - RPC Binding handle
hFileFind [in] - File handle
bCopyToServer [in] - Copy direction
lpcwstrFileName [in] - Name of file generated on the server
(in use for rundown purposes only if bCopyToServer is TRUE)
pJobQueue [in] - Pointer to the job queue containing thr preview file
(in use for rundown purposes only if bCopyToServer is FALSE)
Return Value:
Returns a pointer to a newly created handle
--*/
{
DEBUG_FUNCTION_NAME(TEXT("CreateNewCopyHandle"));
Assert (INVALID_HANDLE_VALUE != hFile);
PHANDLE_ENTRY pHandle = CreateNewHandle (hBinding,
FHT_COPY,
0, // Unused
NULL, // Unused
0); // Unused
if (!pHandle)
{
DebugPrintEx(
DEBUG_ERR,
TEXT("CreateNewHandle failed"));
return NULL;
}
//
// Store file handle and direction in the new context
//
pHandle->hFile = hFile;
pHandle->bCopyToServer = bCopyToServer;
pHandle->bError = FALSE;
if (bCopyToServer)
{
//
// If this is a copy operation to the server, we keep the name of the file
// created in the server's queue so that in the rundown operation we can delete this file.
//
Assert (lstrlen (lpcwstrFileName) < MAX_PATH); //wstrFileName is MAX_PATH size
wcsncpy (pHandle->wstrFileName, lpcwstrFileName, ARR_SIZE(pHandle->wstrFileName)-1);
}
else
{
pHandle->pJobQueue = pJobQueue;
}
return pHandle;
} // CreateNewCopyHandle
VOID
CloseFaxHandle(
PHANDLE_ENTRY pHandleEntry
)
{
//
// note that the HandleEntry may be a context handle,
// which may be NULL in some cases. Do nothing if
// this is the case
//
DEBUG_FUNCTION_NAME(TEXT("CloseFaxHandle"));
Assert (pHandleEntry);
EnterCriticalSection( &g_CsHandleTable );
RemoveEntryList( &pHandleEntry->ListEntry );
if ((pHandleEntry->Type == FHT_SERVICE) && !(pHandleEntry->bReleased))
{
SafeDecIdleCounter (&g_dwConnectionCount);
}
else if (pHandleEntry->Type == FHT_MSGENUM)
{
if (!FindClose (pHandleEntry->hFile))
{
DebugPrintEx( DEBUG_ERR,
TEXT("FindClose returned error code %ld"),
GetLastError());
}
}
else if (pHandleEntry->Type == FHT_COPY)
{
if (!CloseHandle (pHandleEntry->hFile))
{
DebugPrintEx( DEBUG_ERR,
TEXT("CloseHandle returned error code %ld"),
GetLastError());
}
if (pHandleEntry->bError && pHandleEntry->bCopyToServer)
{
//
// We found an error while copying to the server.
// Remove temporary file created in the server's queue
//
if (!DeleteFile (pHandleEntry->wstrFileName))
{
DWORD dwRes = GetLastError ();
DebugPrintEx( DEBUG_ERR,
TEXT("DeleteFile (%s) returned error code %ld"),
pHandleEntry->wstrFileName,
dwRes);
}
}
if (FALSE == pHandleEntry->bCopyToServer)
{
if (pHandleEntry->pJobQueue)
{
//
// Decrease ref count only for queued jobs
//
EnterCriticalSection (&g_CsQueue);
DecreaseJobRefCount (pHandleEntry->pJobQueue, TRUE, TRUE, TRUE);
LeaveCriticalSection (&g_CsQueue);
}
}
}
MemFree( pHandleEntry );
LeaveCriticalSection( &g_CsHandleTable );
}
BOOL
IsPortOpenedForModify(
PLINE_INFO LineInfo
)
{
PLIST_ENTRY Next;
PHANDLE_ENTRY HandleEntry;
EnterCriticalSection( &g_CsHandleTable );
Next = g_HandleTableListHead.Flink;
if (Next == NULL)
{
LeaveCriticalSection( &g_CsHandleTable );
return FALSE;
}
while ((ULONG_PTR)Next != (ULONG_PTR)&g_HandleTableListHead) {
HandleEntry = CONTAINING_RECORD( Next, HANDLE_ENTRY, ListEntry );
if (HandleEntry->Type == FHT_PORT && (HandleEntry->Flags & PORT_OPEN_MODIFY) && HandleEntry->LineInfo == LineInfo)
{
LeaveCriticalSection( &g_CsHandleTable );
return TRUE;
}
Next = HandleEntry->ListEntry.Flink;
}
LeaveCriticalSection( &g_CsHandleTable );
return FALSE;
}
DWORD
FindClientAPIVersion (
handle_t hFaxHandle
)
/*++
Routine name : FindClientAPIVersion
Routine description:
Finds the API version of a connected client by its RPC binding handle
Author:
Eran Yariv (EranY), Mar, 2001
Arguments:
hFaxHandle [in] - RPC binding handle
Return Value:
Client API version
--*/
{
PLIST_ENTRY pNext;
DEBUG_FUNCTION_NAME(TEXT("FindClientAPIVersion"));
EnterCriticalSection (&g_CsHandleTable);
pNext = g_HandleTableListHead.Flink;
if (pNext == NULL)
{
ASSERT_FALSE;
DebugPrintEx( DEBUG_ERR,
TEXT("g_CsHandleTable is corrupted"));
LeaveCriticalSection (&g_CsHandleTable);
return FAX_API_VERSION_0;
}
while ((ULONG_PTR)pNext != (ULONG_PTR)&g_HandleTableListHead)
{
PHANDLE_ENTRY pHandleEntry = CONTAINING_RECORD(pNext, HANDLE_ENTRY, ListEntry);
if ( ((FHT_SERVICE == pHandleEntry->Type) || (FHT_MSGENUM == pHandleEntry->Type) ) &&
(pHandleEntry->hBinding == hFaxHandle)
)
{
DWORD dwRes = pHandleEntry->dwClientAPIVersion;
LeaveCriticalSection (&g_CsHandleTable);
return dwRes;
}
pNext = pHandleEntry->ListEntry.Flink;
}
LeaveCriticalSection (&g_CsHandleTable);
DebugPrintEx( DEBUG_ERR,
TEXT("No matching client entry for binding handle %08p"),
hFaxHandle);
return FAX_API_VERSION_0;
} // FindClientAPIVersion