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.

148 lines
4.1 KiB

  1. /*
  2. * Copyright (c) Microsoft Corporation
  3. *
  4. * Module Name :
  5. * unlo.c
  6. *
  7. * Shut down and delete functions
  8. * Where possible, code has been obtained from BINL server.
  9. *
  10. * Sadagopan Rajaram -- Oct 14, 1999
  11. *
  12. */
  13. #include "tcsrv.h"
  14. #include <ntddser.h>
  15. #include "tcsrvc.h"
  16. #include "proto.h"
  17. NTSTATUS
  18. DeleteComPort(
  19. LPTSTR device
  20. )
  21. /*++
  22. Deletes a Com port from the list
  23. --*/
  24. {
  25. BOOL ret;
  26. NTSTATUS Status;
  27. PCOM_PORT_INFO pPrev,pComPortInfo;
  28. HANDLE Thread;
  29. int index,i;
  30. EnterCriticalSection(&GlobalMutex);
  31. if(TCGlobalServiceStatus.dwCurrentState == SERVICE_STOP_PENDING){
  32. // Entire Service is shutting down.
  33. LeaveCriticalSection(&GlobalMutex);
  34. return STATUS_SUCCESS;
  35. } // find the device needed to be deleted.
  36. pComPortInfo = FindDevice(device,&index);
  37. if(!pComPortInfo){
  38. // Bah ! give me an existing device.
  39. LeaveCriticalSection(&GlobalMutex);
  40. return (STATUS_OBJECT_NAME_NOT_FOUND);
  41. }
  42. // Set the terminate event on the com port.
  43. ret = SetEvent(pComPortInfo->Events[3]);
  44. Thread = Threads[index];
  45. LeaveCriticalSection(&GlobalMutex);
  46. // wait for the com port thread to finish.
  47. Status = NtWaitForSingleObject(Thread, FALSE, NULL);
  48. if (Status == WAIT_FAILED) {
  49. // catastrophe
  50. return Status;
  51. }
  52. EnterCriticalSection(&GlobalMutex);
  53. // do this again as another delete or insert may have
  54. // changed the index, though how is beyond me :-)
  55. // if we are already shutting down the service.
  56. if(TCGlobalServiceStatus.dwCurrentState == SERVICE_STOP_PENDING){
  57. // Entire Service is shutting down.
  58. LeaveCriticalSection(&GlobalMutex);
  59. return STATUS_SUCCESS;
  60. }
  61. pComPortInfo = FindDevice(device,&index);
  62. if(!pComPortInfo){
  63. LeaveCriticalSection(&GlobalMutex);
  64. return (STATUS_OBJECT_NAME_NOT_FOUND);
  65. }
  66. if(pComPortInfo == ComPortInfo){
  67. ComPortInfo = pComPortInfo->Next;
  68. }
  69. else{
  70. pPrev = ComPortInfo;
  71. while(pPrev->Next != pComPortInfo){// Can never fail
  72. pPrev = pPrev->Next;
  73. }
  74. pPrev->Next = pComPortInfo->Next;
  75. }
  76. pComPortInfo->Next = NULL;
  77. FreeComPortInfo(pComPortInfo);
  78. NtClose(Threads[index]);
  79. for(i=index;i<ComPorts-1;i++){
  80. // move the threads array to the proper place
  81. Threads[i]=Threads[i+1];
  82. }
  83. ComPorts --;
  84. if(ComPorts == 0){
  85. TCFree(Threads);
  86. Threads=NULL;
  87. }
  88. LeaveCriticalSection(&GlobalMutex);
  89. return(STATUS_SUCCESS);
  90. }
  91. VOID
  92. Shutdown(
  93. NTSTATUS Status
  94. )
  95. /*++
  96. Cleanly shut down the service. delete all threads, cancel all outstanding IRPs.
  97. Close all open sockets.
  98. --*/
  99. {
  100. PCOM_PORT_INFO pTemp;
  101. int i;
  102. SetEvent(TerminateService); // all threads down
  103. // Can do this another way,
  104. // We can take each comport device and
  105. // delete it using the DeleteComPort
  106. // function. But, this allows for maximum
  107. // parallelism even in shutting down :-)
  108. if(Threads){
  109. WaitForMultipleObjects(ComPorts,Threads, TRUE, INFINITE);
  110. // BUGBUG - what if thread is a rougue thread and
  111. // never comes back. Must use some reasonable
  112. // time out.
  113. // Theory says INFINITE is the safest :-)
  114. }
  115. //All threads terminated.
  116. // Now start freeing all global memory
  117. // just using the locks as a safety measure.
  118. EnterCriticalSection(&GlobalMutex);
  119. while(ComPortInfo){
  120. pTemp = ComPortInfo;
  121. ComPortInfo=pTemp->Next;
  122. pTemp->Next = NULL;
  123. FreeComPortInfo(pTemp);
  124. }
  125. TCFree(Threads);
  126. NtClose(TerminateService);
  127. LeaveCriticalSection(&GlobalMutex);
  128. UNINITIALIZE_TRACE_MEMORY
  129. //All done, now print status and exit.
  130. TCGlobalServiceStatus.dwCurrentState = SERVICE_STOPPED;
  131. SetServiceStatus(TCGlobalServiceStatusHandle, &TCGlobalServiceStatus);
  132. TCDebugPrint(("Shutdown Status = %lx\n",Status));
  133. return;
  134. }