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.

205 lines
4.4 KiB

  1. /*++
  2. Copyright (c) 1996, 1997 Microsoft Corporation
  3. Module Name:
  4. defer.cpp
  5. Abstract:
  6. This module contains routines to perform deferred "on-demand" loading
  7. of the Protected Storage server.
  8. Furthermore, this module implements a routine, IsServiceAvailable(),
  9. which is a high-performance test that can be used to determine if the
  10. protected storage server is running. This test is performed prior
  11. to attempting any more expensive operations against the server (eg,
  12. RPC binding).
  13. This defer loading code is only relevant for Protected Storage when
  14. running on Windows 95.
  15. Author:
  16. Scott Field (sfield) 23-Jan-97
  17. --*/
  18. #include <windows.h>
  19. #include <wincrypt.h>
  20. #include "pstrpc.h"
  21. #include "pstprv.h"
  22. #include "service.h"
  23. #include "crtem.h"
  24. #include "unicode.h"
  25. #define SERVICE_WAIT_TIMEOUT (10*1000) // 10 seconds
  26. BOOL StartService95(VOID);
  27. BOOL GetServiceImagePath95(LPSTR ImagePath, LPDWORD cchImagePath);
  28. BOOL
  29. IsServiceAvailable(VOID)
  30. /*++
  31. This routine checks to see if the secure storage service is available, to
  32. avoid causing logon delays if the service is not yet available or has been
  33. stopped.
  34. OpenEventA is used to allow this to be callable from WinNT or Win95,
  35. since the Win95 cred manager also needs this service.
  36. --*/
  37. {
  38. HANDLE hEvent;
  39. DWORD dwWaitState;
  40. if( FIsWinNT5() ) {
  41. hEvent = OpenEventA(SYNCHRONIZE, FALSE, PST_EVENT_INIT_NT5);
  42. } else {
  43. hEvent = OpenEventA(SYNCHRONIZE, FALSE, PST_EVENT_INIT);
  44. }
  45. if(hEvent == NULL) {
  46. //
  47. // if running on Win95, try to start the server/service
  48. //
  49. if(!FIsWinNT())
  50. return StartService95();
  51. return FALSE;
  52. }
  53. dwWaitState = WaitForSingleObject(hEvent, SERVICE_WAIT_TIMEOUT);
  54. CloseHandle(hEvent);
  55. if(dwWaitState != WAIT_OBJECT_0)
  56. return FALSE;
  57. return TRUE;
  58. }
  59. BOOL
  60. StartService95(VOID)
  61. {
  62. HANDLE hEvent;
  63. DWORD dwWaitState;
  64. CHAR ServicePath[MAX_PATH+1];
  65. DWORD cchServicePath = MAX_PATH;
  66. STARTUPINFO si;
  67. PROCESS_INFORMATION pi;
  68. DWORD dwWaitTimeout = 2500;
  69. BOOL bSuccess = FALSE;
  70. //
  71. // create + check status of service init flag.
  72. //
  73. hEvent = CreateEventA(
  74. NULL,
  75. TRUE,
  76. FALSE,
  77. PST_EVENT_INIT
  78. );
  79. if(hEvent == NULL)
  80. return FALSE;
  81. //
  82. // check for race condition with multiple callers creating event.
  83. //
  84. if(GetLastError() == ERROR_ALREADY_EXISTS) {
  85. WaitForSingleObject( hEvent, SERVICE_WAIT_TIMEOUT );
  86. CloseHandle(hEvent);
  87. return TRUE;
  88. }
  89. if(!GetServiceImagePath95(ServicePath, &cchServicePath)) {
  90. CloseHandle(hEvent);
  91. return FALSE;
  92. }
  93. ZeroMemory(&si, sizeof(si));
  94. bSuccess = CreateProcessA(
  95. ServicePath,
  96. NULL,
  97. NULL,
  98. NULL,
  99. FALSE,
  100. DETACHED_PROCESS,
  101. NULL,
  102. NULL,
  103. &si,
  104. &pi
  105. );
  106. if(bSuccess) {
  107. CloseHandle(pi.hProcess);
  108. CloseHandle(pi.hThread);
  109. dwWaitTimeout = SERVICE_WAIT_TIMEOUT;
  110. }
  111. dwWaitState = WaitForSingleObject(hEvent, dwWaitTimeout);
  112. if(dwWaitState != WAIT_OBJECT_0)
  113. bSuccess = FALSE;
  114. CloseHandle(hEvent);
  115. return bSuccess;
  116. }
  117. BOOL
  118. GetServiceImagePath95(
  119. LPSTR ImagePath,
  120. LPDWORD cchImagePath // IN, OUT
  121. )
  122. {
  123. HKEY hBaseKey = NULL;
  124. LPCWSTR ServicePath = L"SYSTEM\\CurrentControlSet\\Services\\" SZSERVICENAME L"\\Parameters";
  125. DWORD dwCreate;
  126. DWORD dwType;
  127. LONG lRet;
  128. lRet = RegCreateKeyExU(
  129. HKEY_LOCAL_MACHINE,
  130. ServicePath,
  131. 0,
  132. NULL, // address of class string
  133. 0,
  134. KEY_QUERY_VALUE,
  135. NULL,
  136. &hBaseKey,
  137. &dwCreate);
  138. if(lRet == ERROR_SUCCESS) {
  139. lRet = RegQueryValueExA(
  140. hBaseKey,
  141. "ImagePath",
  142. NULL,
  143. &dwType,
  144. (PBYTE)ImagePath,
  145. cchImagePath);
  146. }
  147. if(hBaseKey)
  148. RegCloseKey(hBaseKey);
  149. if(lRet != ERROR_SUCCESS) {
  150. SetLastError((DWORD)lRet);
  151. return FALSE;
  152. }
  153. return TRUE;
  154. }