mirror of https://github.com/lianthony/NT4.0
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.
174 lines
3.9 KiB
174 lines
3.9 KiB
#define NOOLE
|
|
#include <windows.h>
|
|
#include <sysinc.h>
|
|
#include <lpcsem.hxx>
|
|
|
|
#define LPC_SEM_THROW RaiseException(GetLastError(), 0, 0, NULL)
|
|
|
|
LPC_SEM::LPC_SEM(
|
|
LONG cSemInitial,
|
|
LONG cSemMax
|
|
)
|
|
{
|
|
hSemaphore = CreateSemaphore(NULL, cSemInitial, cSemMax, NULL);
|
|
|
|
ASSERT(hSemaphore != NULL);
|
|
|
|
if (hSemaphore == NULL) {
|
|
#ifdef DEBUGRPC
|
|
PrintToDebugger("LRPC: CreateSemaphore failed %d\n", GetLastError());
|
|
#endif
|
|
LPC_SEM_THROW;
|
|
return;
|
|
}
|
|
|
|
OwnerProcessId = GetCurrentProcessId();
|
|
}
|
|
|
|
LPC_SEM::LPC_SEM(
|
|
LPC_SEM & ExistingSemaphore
|
|
)
|
|
{
|
|
BOOL BooleanStatus;
|
|
HANDLE hOwnerProcess;
|
|
HANDLE hCurrentProcess;
|
|
|
|
hOwnerProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, ExistingSemaphore.OwnerProcessId);
|
|
|
|
ASSERT(hOwnerProcess != NULL);
|
|
|
|
if (hOwnerProcess == NULL) {
|
|
#ifdef DEBUGRPC
|
|
PrintToDebugger("LRPC: OpenProcess failed %d\n", GetLastError());
|
|
#endif
|
|
LPC_SEM_THROW;
|
|
return;
|
|
}
|
|
|
|
BooleanStatus = DuplicateHandle(GetCurrentProcess(),
|
|
GetCurrentProcess(),
|
|
GetCurrentProcess(),
|
|
&hCurrentProcess,
|
|
0,
|
|
FALSE,
|
|
DUPLICATE_SAME_ACCESS);
|
|
|
|
ASSERT(BooleanStatus == TRUE);
|
|
|
|
if (BooleanStatus == FALSE) {
|
|
#ifdef DEBUGRPC
|
|
PrintToDebugger("LRPC: DuplicateHandle failed %d\n", GetLastError());
|
|
#endif
|
|
LPC_SEM_THROW;
|
|
return;
|
|
}
|
|
|
|
BooleanStatus = DuplicateHandle(hOwnerProcess,
|
|
ExistingSemaphore.hSemaphore,
|
|
hCurrentProcess,
|
|
&hSemaphore,
|
|
SEMAPHORE_ALL_ACCESS,
|
|
FALSE,
|
|
0);
|
|
|
|
ASSERT(BooleanStatus == TRUE);
|
|
|
|
if (BooleanStatus == FALSE) {
|
|
#ifdef DEBUGRPC
|
|
PrintToDebugger("LRPC: DuplicateHandle failed %d\n", GetLastError());
|
|
#endif
|
|
LPC_SEM_THROW;
|
|
return;
|
|
}
|
|
|
|
CloseHandle(hOwnerProcess);
|
|
|
|
CloseHandle(hCurrentProcess);
|
|
|
|
OwnerProcessId = GetCurrentProcessId();
|
|
}
|
|
|
|
LPC_SEM::~LPC_SEM(
|
|
)
|
|
{
|
|
// BUGBUG: Doing a CloseHandle on a handle obtained from DuplicateHandle
|
|
// seems to invalidate the original handle.
|
|
// CloseHandle(hSemaphore);
|
|
}
|
|
|
|
DWORD
|
|
LPC_SEM::WaitOrOwnerDead(DWORD dwProcessId)
|
|
{
|
|
HANDLE Handles[2];
|
|
DWORD Status;
|
|
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
|
|
if(NULL == hProcess)
|
|
{
|
|
return LPC_SEM_WAIT_PROCESS_DEAD;
|
|
}
|
|
Handles[0] = hProcess;
|
|
Handles[1] = hSemaphore;
|
|
Status = WaitForMultipleObjects(
|
|
DWORD(2),
|
|
(CONST HANDLE*) Handles,
|
|
FALSE,
|
|
INFINITE
|
|
);
|
|
CloseHandle(hProcess);
|
|
switch (Status)
|
|
{
|
|
case WAIT_OBJECT_0 + 1:
|
|
return LPC_SEM_WAIT_SUCCESS;
|
|
|
|
case WAIT_OBJECT_0:
|
|
return LPC_SEM_WAIT_PROCESS_DEAD;
|
|
|
|
case WAIT_ABANDONED_0:
|
|
return LPC_SEM_WAIT_PROCESS_DEAD;
|
|
|
|
case WAIT_FAILED:
|
|
#ifdef DEBUGRPC
|
|
PrintToDebugger("LRPC sem wait failed: %d\n",GetLastError());
|
|
#endif
|
|
return LPC_SEM_WAIT_PROCESS_DEAD;
|
|
|
|
default:
|
|
// should never be here...
|
|
ASSERT(0);
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
LPC_SEM::Wait(
|
|
DWORD Timeout
|
|
)
|
|
{
|
|
DWORD Status;
|
|
Status = WaitForSingleObject(hSemaphore, Timeout);
|
|
if (Status == WAIT_FAILED) {
|
|
return (GetLastError());
|
|
} else {
|
|
return (Status);
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
LPC_SEM::Wait(
|
|
)
|
|
{
|
|
if (WaitForSingleObject(hSemaphore, INFINITE) == WAIT_FAILED) {
|
|
return (GetLastError());
|
|
}
|
|
return (ERROR_SUCCESS);
|
|
}
|
|
|
|
DWORD
|
|
LPC_SEM::Release()
|
|
{
|
|
if (ReleaseSemaphore(hSemaphore, 1, NULL) == FALSE) {
|
|
return (GetLastError());
|
|
}
|
|
return (ERROR_SUCCESS);
|
|
}
|
|
|