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.
|
|
/*
* Copyright (c) Microsoft Corporation * * Module Name : * unlo.c * * Shut down and delete functions * Where possible, code has been obtained from BINL server. * * Sadagopan Rajaram -- Oct 14, 1999 * */ #include "tcsrv.h"
#include <ntddser.h>
#include "tcsrvc.h"
#include "proto.h"
NTSTATUS DeleteComPort( LPTSTR device ) /*++
Deletes a Com port from the list --*/ {
BOOL ret; NTSTATUS Status; PCOM_PORT_INFO pPrev,pComPortInfo; HANDLE Thread; int index,i;
EnterCriticalSection(&GlobalMutex); if(TCGlobalServiceStatus.dwCurrentState == SERVICE_STOP_PENDING){ // Entire Service is shutting down.
LeaveCriticalSection(&GlobalMutex); return STATUS_SUCCESS; } // find the device needed to be deleted.
pComPortInfo = FindDevice(device,&index); if(!pComPortInfo){ // Bah ! give me an existing device.
LeaveCriticalSection(&GlobalMutex); return (STATUS_OBJECT_NAME_NOT_FOUND); } // Set the terminate event on the com port.
ret = SetEvent(pComPortInfo->Events[3]); Thread = Threads[index]; LeaveCriticalSection(&GlobalMutex); // wait for the com port thread to finish.
Status = NtWaitForSingleObject(Thread, FALSE, NULL); if (Status == WAIT_FAILED) { // catastrophe
return Status; } EnterCriticalSection(&GlobalMutex); // do this again as another delete or insert may have
// changed the index, though how is beyond me :-)
// if we are already shutting down the service.
if(TCGlobalServiceStatus.dwCurrentState == SERVICE_STOP_PENDING){ // Entire Service is shutting down.
LeaveCriticalSection(&GlobalMutex); return STATUS_SUCCESS; } pComPortInfo = FindDevice(device,&index); if(!pComPortInfo){ LeaveCriticalSection(&GlobalMutex); return (STATUS_OBJECT_NAME_NOT_FOUND); } if(pComPortInfo == ComPortInfo){ ComPortInfo = pComPortInfo->Next; } else{ pPrev = ComPortInfo; while(pPrev->Next != pComPortInfo){// Can never fail
pPrev = pPrev->Next; } pPrev->Next = pComPortInfo->Next; } pComPortInfo->Next = NULL; FreeComPortInfo(pComPortInfo); NtClose(Threads[index]); for(i=index;i<ComPorts-1;i++){ // move the threads array to the proper place
Threads[i]=Threads[i+1]; } ComPorts --; if(ComPorts == 0){ TCFree(Threads); Threads=NULL; } LeaveCriticalSection(&GlobalMutex); return(STATUS_SUCCESS);
}
VOID Shutdown( NTSTATUS Status ) /*++
Cleanly shut down the service. delete all threads, cancel all outstanding IRPs. Close all open sockets. --*/ { PCOM_PORT_INFO pTemp; int i;
SetEvent(TerminateService); // all threads down
// Can do this another way,
// We can take each comport device and
// delete it using the DeleteComPort
// function. But, this allows for maximum
// parallelism even in shutting down :-)
if(Threads){ WaitForMultipleObjects(ComPorts,Threads, TRUE, INFINITE); // BUGBUG - what if thread is a rougue thread and
// never comes back. Must use some reasonable
// time out.
// Theory says INFINITE is the safest :-)
} //All threads terminated.
// Now start freeing all global memory
// just using the locks as a safety measure.
EnterCriticalSection(&GlobalMutex); while(ComPortInfo){ pTemp = ComPortInfo; ComPortInfo=pTemp->Next; pTemp->Next = NULL; FreeComPortInfo(pTemp);
} TCFree(Threads); NtClose(TerminateService); LeaveCriticalSection(&GlobalMutex);
UNINITIALIZE_TRACE_MEMORY //All done, now print status and exit.
TCGlobalServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(TCGlobalServiceStatusHandle, &TCGlobalServiceStatus);
TCDebugPrint(("Shutdown Status = %lx\n",Status)); return; }
|