Source code of Windows XP (NT5)
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.

399 lines
13 KiB

  1. /*************************************************************************
  2. * Microsoft Windows NT *
  3. * *
  4. * Copyright(c) Microsoft Corp., 1994 *
  5. * *
  6. * Revision History: *
  7. * *
  8. * Jan. 23,94 Koti Created *
  9. * *
  10. * Description: *
  11. * *
  12. * This file contains functions for starting and stopping LPD service *
  13. * *
  14. *************************************************************************/
  15. #include "lpd.h"
  16. // Globals:
  17. SERVICE_STATUS ssSvcStatusGLB;
  18. SERVICE_STATUS_HANDLE hSvcHandleGLB = 0;
  19. HANDLE hEventShutdownGLB;
  20. HANDLE hEventLastThreadGLB;
  21. HANDLE hLogHandleGLB;
  22. // head of the linked list of SOCKCONN structures (one link per connection)
  23. SOCKCONN scConnHeadGLB;
  24. // to guard access to linked list of pscConn
  25. CRITICAL_SECTION csConnSemGLB;
  26. // max users that can be connected concurrently
  27. DWORD dwMaxUsersGLB;
  28. DWORD MaxQueueLength;
  29. BOOL fJobRemovalEnabledGLB=TRUE;
  30. BOOL fAllowPrintResumeGLB=TRUE;
  31. BOOL fAlwaysRawGLB=FALSE;
  32. DWORD dwRecvTimeout;
  33. BOOL fShuttingDownGLB=FALSE;
  34. CHAR szNTVersion[8];
  35. CHAR *g_ppszStrings[ LPD_CSTRINGS ];
  36. // Info shared by all threads, protected by CRITICAL_SECTION.
  37. COMMON_LPD Common;
  38. /*****************************************************************************
  39. * *
  40. * LoadStrings(): *
  41. * Load a bunch of strings defined in the .mc file. *
  42. * *
  43. * Returns: *
  44. * TRUE if everything went ok *
  45. * FALSE if a string couldn't be loaded *
  46. * *
  47. * Parameters: *
  48. * None *
  49. * *
  50. * History: *
  51. * June.27, 96 Frankbee Created *
  52. * *
  53. *****************************************************************************/
  54. BOOL LoadStrings()
  55. {
  56. DWORD dwSuccess;
  57. HMODULE hModule;
  58. DWORD dwID;
  59. hModule = LoadLibrary( TEXT(LPD_SERVICE_NAME) );
  60. if (hModule == NULL)
  61. {
  62. return(FALSE);
  63. }
  64. memset( g_ppszStrings, 0, LPD_CSTRINGS * sizeof( CHAR * ) );
  65. for ( dwID = LPD_FIRST_STRING; dwID <= LPD_LAST_STRING; dwID++ )
  66. {
  67. // &g_ppszStrings[(dwID - LPD_FIRST_STRING)][0],
  68. dwSuccess = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
  69. FORMAT_MESSAGE_FROM_HMODULE,
  70. hModule, // search local process
  71. dwID,
  72. MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT),
  73. (LPSTR)(g_ppszStrings + (dwID - LPD_FIRST_STRING)),
  74. 1,
  75. NULL );
  76. if (!dwSuccess){
  77. DEBUG_PRINT(("lpd:init.c:29, dwID=%d FormatMessage failed\n", dwID));
  78. goto error;
  79. }
  80. }
  81. FreeLibrary( hModule );
  82. return TRUE;
  83. error:
  84. FreeStrings();
  85. FreeLibrary( hModule );
  86. return FALSE;
  87. }
  88. /*****************************************************************************
  89. * *
  90. * FreeStrings(): *
  91. * Frees the strings loaded by LoadStrings() *
  92. * *
  93. * Returns: *
  94. * VOID * *
  95. * Parameters: *
  96. * None *
  97. * *
  98. * History: *
  99. * June.27, 96 Frankbee Created *
  100. * *
  101. *****************************************************************************/
  102. VOID FreeStrings()
  103. {
  104. int i;
  105. for ( i = 0; i < LPD_CSTRINGS; i++ )
  106. (LocalFree)( g_ppszStrings[i] );
  107. //
  108. // clear the string table for debug builds to prevent access after
  109. // FreeStrings()
  110. //
  111. #if DBG
  112. memset( g_ppszStrings, 0, LPD_CSTRINGS * sizeof( CHAR * ) );
  113. #endif
  114. }
  115. /*****************************************************************************
  116. * *
  117. * InitStuff(): *
  118. * This function initializes hEventShutdown and other global vars *
  119. * *
  120. * Returns: *
  121. * TRUE if everything went ok *
  122. * FALSE if something went wrong *
  123. * *
  124. * Parameters: *
  125. * None *
  126. * *
  127. * History: *
  128. * Jan.23, 94 Koti Created *
  129. * *
  130. *****************************************************************************/
  131. BOOL InitStuff( )
  132. {
  133. USHORT usVersion;
  134. UCHAR uchTemp;
  135. #ifdef DBG
  136. // MohsinA, 06-Mar-97. lpd isn't starting.
  137. beginlogging( MOSH_LOG_FILE );
  138. #endif
  139. if ( !LoadStrings() )
  140. {
  141. LPD_DEBUG( "LoadStrings() failed in InitStuf\n" );
  142. return FALSE;
  143. }
  144. if ( !InitLogging() )
  145. {
  146. LPD_DEBUG( "InitLogging() FAILed, continuing anyway ...\n" );
  147. }
  148. #if DBG
  149. InitializeListHead(&DbgMemList);
  150. #endif
  151. // main thread blocks for ever on this event, before doing a shutdown
  152. hEventShutdownGLB = CreateEvent( NULL, FALSE, FALSE, NULL );
  153. // when the main thread is ready to shutdown, if there are any active
  154. // threads servicing clients, then main thread blocks on this event
  155. // (the last thread to leave sets the event)
  156. hEventLastThreadGLB = CreateEvent( NULL, FALSE, FALSE, NULL );
  157. if ( ( hEventShutdownGLB == (HANDLE)NULL ) ||
  158. ( hEventLastThreadGLB == (HANDLE)NULL ) )
  159. {
  160. LPD_DEBUG( "CreateEvent() failed in InitStuff\n" );
  161. return( FALSE );
  162. }
  163. scConnHeadGLB.pNext = NULL;
  164. // == Doubly linked list,
  165. // == isempty() iff scConnHeadGLB.pNext == &scConnHeadGLB.
  166. // == && scConnHeadGLB.pPrev == &scConnHeadGLB.
  167. // scConnHeadGLB.pNext = scConnHeadGLB.pPrev = &scConnHeadGLB;
  168. // scConnHeadGLB.cbClients = 0; // Obselete.
  169. memset( &Common, 0, sizeof(Common) );
  170. // csConnSemGLB is the critical section object (guards access to
  171. // scConnHeadGLB, head of the psc linked list)
  172. InitializeCriticalSection( &csConnSemGLB );
  173. // perform debug build initialization
  174. DBG_INIT();
  175. ReadRegistryValues();
  176. // store the version number of NT
  177. usVersion = (USHORT)GetVersion();
  178. uchTemp = (UCHAR)usVersion; // low byte => major version number
  179. usVersion >>= 8; // high byte => minor version number
  180. sprintf( szNTVersion,"%d.%d",uchTemp,(UCHAR)usVersion );
  181. return( TRUE );
  182. } // end InitStuff( )
  183. /*****************************************************************************
  184. * *
  185. * ReadRegistryValues(): *
  186. * This function initializes all variables that we read via registry. If *
  187. * there is a problem and we can't read the registry, we ignore the *
  188. * problem and initialize the variables with our defaults. *
  189. * *
  190. * Returns: *
  191. * Nothing *
  192. * *
  193. * Parameters: *
  194. * None *
  195. * *
  196. * History: *
  197. * Jan.30, 94 Koti Created *
  198. * *
  199. *****************************************************************************/
  200. VOID ReadRegistryValues( VOID )
  201. {
  202. HKEY hLpdKey;
  203. DWORD dwErrcode;
  204. DWORD dwType, dwValue, dwValueSize;
  205. // first set defaults
  206. dwMaxUsersGLB = LPD_MAX_USERS;
  207. MaxQueueLength = LPD_MAX_QUEUE_LENGTH;
  208. fJobRemovalEnabledGLB = TRUE;
  209. fAllowPrintResumeGLB = TRUE;
  210. fAlwaysRawGLB = FALSE;
  211. dwRecvTimeout = RECV_TIMEOUT;
  212. dwErrcode = RegOpenKeyEx( HKEY_LOCAL_MACHINE, LPD_PARMS_REGISTRY_PATH,
  213. 0, KEY_ALL_ACCESS, &hLpdKey );
  214. if ( dwErrcode != ERROR_SUCCESS )
  215. {
  216. return;
  217. }
  218. // Read in the dwMaxUsersGLB parm
  219. dwValueSize = sizeof( DWORD );
  220. dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_MAXUSERS, NULL,
  221. &dwType, (LPBYTE)&dwValue, &dwValueSize );
  222. if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) )
  223. {
  224. dwMaxUsersGLB = dwValue;
  225. }
  226. //
  227. // Read in the MaxQueueLength
  228. //
  229. dwValueSize = sizeof( DWORD );
  230. dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_MAX_QUEUE_LENGTH, NULL,
  231. &dwType, (LPBYTE)&dwValue, &dwValueSize );
  232. if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) )
  233. {
  234. MaxQueueLength = dwValue;
  235. }
  236. //
  237. // Read in the fJobRemovalEnabledGLB parm
  238. dwValueSize = sizeof( DWORD );
  239. dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_JOBREMOVAL, NULL,
  240. &dwType, (LPBYTE)&dwValue, &dwValueSize );
  241. if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) &&
  242. ( dwValue == 0 ) )
  243. {
  244. fJobRemovalEnabledGLB = FALSE;
  245. }
  246. // Read in the fAllowPrintResumeGLB parm
  247. dwValueSize = sizeof( DWORD );
  248. dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_PRINTRESUME, NULL,
  249. &dwType, (LPBYTE)&dwValue, &dwValueSize );
  250. if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) &&
  251. ( dwValue == 0 ) )
  252. {
  253. fAllowPrintResumeGLB = FALSE;
  254. }
  255. // Read in the fAlwaysRawGLB parm
  256. dwValueSize = sizeof( DWORD );
  257. dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_ALWAYSRAW, NULL,
  258. &dwType, (LPBYTE)&dwValue, &dwValueSize );
  259. if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) &&
  260. ( dwValue == 1 ) )
  261. {
  262. fAlwaysRawGLB = TRUE;
  263. }
  264. // Read in the dwRecvTimeout parm
  265. dwValueSize = sizeof( DWORD );
  266. dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_RECV_TIMEOUT, NULL,
  267. &dwType, (LPBYTE)&dwValue, &dwValueSize );
  268. if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) )
  269. {
  270. dwRecvTimeout = dwValue;
  271. }
  272. RegCloseKey (hLpdKey);
  273. } // end ReadRegistryValues()