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.

742 lines
34 KiB

  1. /*======================================================================================//
  2. | //
  3. |Copyright (c) 1998 Sequent Computer Systems, Incorporated //
  4. | //
  5. |Description: //
  6. | //
  7. |---------------------------------------------------------------------------------------//
  8. | This file implements the CProcConClient class methods defined in ProcConSvc.h //
  9. |---------------------------------------------------------------------------------------//
  10. | //
  11. |Created: //
  12. | //
  13. | Jarl McDonald 07-98 //
  14. | //
  15. |Revision History: //
  16. | //
  17. |=======================================================================================*/
  18. #include "ProcConSvc.h"
  19. const PCINT32 SIGNATURE = 0xd06eface;
  20. // CProcConClient Constructor...
  21. CProcConClient::CProcConClient( ClientContext *ctxt ) : m_impersonating( FALSE ),
  22. m_cPC( *ctxt->cPC ), m_cDB( *ctxt->cDB ),
  23. m_cUser( *ctxt->cUser ),
  24. m_hPipe( ctxt->hPipe), m_clientNo( ctxt->clientNo ),
  25. m_inBufChars( ctxt->inBufChars ), m_outBufChars( ctxt->outBufChars )
  26. {
  27. delete ctxt; // we're done with this
  28. m_inBuf = (TCHAR *) new char[m_inBufChars];
  29. if ( !m_inBuf ) PCLogNoMemory( TEXT("AllocInBuffer"), m_inBufChars );
  30. m_outBuf = (TCHAR *) new char[m_outBufChars];
  31. if ( !m_outBuf ) PCLogNoMemory( TEXT("AllocOutBuffer"), m_outBufChars );
  32. m_hReadEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  33. if ( !m_hReadEvent )
  34. PCLogUnExError( TEXT("PipeRead"), TEXT("CreateEvent") );
  35. m_hWriteEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  36. if ( !m_hWriteEvent )
  37. PCLogUnExError( TEXT("PipeWrite"), TEXT("CreateEvent") );
  38. memset( &m_olRead, 0, sizeof(m_olRead ) );
  39. memset( &m_olWrite, 0, sizeof(m_olWrite ) );
  40. m_olRead.hEvent = m_hReadEvent;
  41. m_olWrite.hEvent = m_hWriteEvent;
  42. }
  43. // CProcConClient Destructor...
  44. CProcConClient::~CProcConClient( void )
  45. {
  46. if ( m_hPipe ) {
  47. FlushFileBuffers( m_hPipe );
  48. DisconnectNamedPipe( m_hPipe );
  49. CloseHandle( m_hPipe );
  50. m_hPipe = NULL;
  51. if ( m_impersonating && !RevertToSelf() )
  52. PCLogUnExError( TEXT("PCClient"), TEXT("RevertToSelf") );
  53. }
  54. if ( m_hReadEvent ) CloseHandle( m_hReadEvent );
  55. if ( m_hWriteEvent ) CloseHandle( m_hWriteEvent );
  56. if ( m_inBuf ) delete [] ((char *) m_inBuf);
  57. if ( m_outBuf ) delete [] ((char *) m_outBuf);
  58. m_hReadEvent = m_hWriteEvent = m_inBuf = m_outBuf = NULL;
  59. }
  60. //--------------------------------------------------------------------------------------------//
  61. // Function to determine if all CProcConClient initial conditions have been met //
  62. // Input: None //
  63. // Returns: TRUE if ready, FALSE if not //
  64. //--------------------------------------------------------------------------------------------//
  65. BOOL CProcConClient::ReadyToRun( void ) {
  66. return m_hPipe && m_hReadEvent && m_hWriteEvent && m_inBuf && m_outBuf;
  67. }
  68. //--------------------------------------------------------------------------------------------//
  69. // CProcConClient thread function -- this function runs in its own thread //
  70. // This function handles all pipe reads, writes and processing for a single connection. //
  71. // Input: None //
  72. // Returns: 0 //
  73. // Note: This thread owns the pipe that it is constructed with and terminates //
  74. // when the pipe is closed by the client. //
  75. //--------------------------------------------------------------------------------------------//
  76. PCULONG32 CProcConClient::Run( void )
  77. {
  78. PCULONG32 bytesDone, bytesToWrite, rc;
  79. HANDLE waitList[] = { m_olRead.hEvent, m_olWrite.hEvent, m_cPC.GetShutEvent() };
  80. BOOL inBufEmpty = TRUE, outBufEmpty = TRUE, reading = FALSE, writing = FALSE;
  81. for ( BOOL quit = FALSE; !quit && !m_cPC.GotShutdown(); ) {
  82. // Initiate pipe read if needed...
  83. if ( !reading && inBufEmpty ) {
  84. rc = ReadFile( m_hPipe, m_inBuf, m_inBufChars, &bytesDone, &m_olRead );
  85. if ( !rc && GetLastError() != ERROR_IO_PENDING ) {
  86. if ( GetLastError() != ERROR_BROKEN_PIPE )
  87. PCLogUnExError( TEXT("PCClient"), TEXT("ReadPipe") );
  88. quit = TRUE;
  89. }
  90. else reading = TRUE;
  91. }
  92. // Process any pending data...
  93. if ( !writing && outBufEmpty && !inBufEmpty ) {
  94. inBufEmpty = TRUE;
  95. if ( ProcessRequest( bytesDone, &bytesToWrite ) )
  96. outBufEmpty = FALSE;
  97. }
  98. // Initiate pipe write if needed...
  99. if ( !writing && !outBufEmpty ) {
  100. rc = WriteFile( m_hPipe, m_outBuf, bytesToWrite, &bytesDone, &m_olWrite );
  101. if ( !rc && GetLastError() != ERROR_IO_PENDING ) {
  102. if ( GetLastError() != ERROR_BROKEN_PIPE && GetLastError() != ERROR_NO_DATA )
  103. PCLogUnExError( TEXT("PCClient"), TEXT("WritePipe") );
  104. quit = TRUE;
  105. }
  106. else writing = TRUE;
  107. }
  108. // If we're quitting, don't enter wait...
  109. if ( quit || m_cPC.GotShutdown() ) continue;
  110. // Wait for something to happen...
  111. rc = WaitForMultipleObjects( ENTRY_COUNT( waitList ), waitList, FALSE, INFINITE );
  112. if ( rc == WAIT_FAILED ) {
  113. PCLogUnExError( TEXT("PCClient"), TEXT("Wait") );
  114. break;
  115. }
  116. // Process wait completion...
  117. switch ( rc - WAIT_OBJECT_0 ) {
  118. case 0: // read completed
  119. reading = inBufEmpty = FALSE;
  120. if ( !GetOverlappedResult( m_hPipe, &m_olRead, &bytesDone, TRUE ) ) {
  121. if ( GetLastError() != ERROR_BROKEN_PIPE && GetLastError() != ERROR_NO_DATA )
  122. PCLogUnExError( TEXT("PCClient"), TEXT("ReadResult") );
  123. quit = TRUE;
  124. }
  125. ResetEvent( m_olRead.hEvent );
  126. break;
  127. case 1: // write completed
  128. writing = FALSE;
  129. outBufEmpty = TRUE;
  130. if ( !GetOverlappedResult( m_hPipe, &m_olWrite, &bytesDone, TRUE ) || bytesToWrite != bytesDone ) {
  131. if ( GetLastError() != ERROR_BROKEN_PIPE && GetLastError() != ERROR_NO_DATA )
  132. PCLogUnExError( TEXT("PCClient"), TEXT("WriteResult") );
  133. quit = TRUE;
  134. }
  135. ResetEvent( m_olWrite.hEvent );
  136. break;
  137. case 2: // quit requested
  138. break;
  139. } // end switch
  140. }
  141. return 0;
  142. }
  143. //--------------------------------------------------------------------------------------------//
  144. // Function to handle impersonation on a request by request basis. All decisions about which //
  145. // types of requests require client impersonation are made in this function. //
  146. // Input: request //
  147. // Returns: TRUE if impersonation was properly set, FALSE otherwise //
  148. //--------------------------------------------------------------------------------------------//
  149. BOOL CProcConClient::Impersonate( PCRequest *req ) {
  150. switch (req->reqType) {
  151. case PCTYPE_PROCLIST: // impersonation not required
  152. break;
  153. case PCTYPE_NAMERULE: // impersonation required
  154. case PCTYPE_JOBSUMMARY:
  155. case PCTYPE_PROCSUMMARY:
  156. case PCTYPE_JOBLIST:
  157. case PCTYPE_PROCDETAIL:
  158. case PCTYPE_JOBDETAIL:
  159. case PCTYPE_SERVERINFO:
  160. case PCTYPE_SERVERPARMS:
  161. case PCTYPE_CONTROL:
  162. if ( !ImpersonateNamedPipeClient( m_hPipe ) ) {
  163. PCLogUnExError( TEXT("PCClient"), TEXT("Impersonate") );
  164. return FALSE;
  165. }
  166. m_impersonating = TRUE;
  167. break;
  168. default:
  169. SetLastError( PCERROR_INVALID_REQUEST );
  170. return FALSE;
  171. }
  172. return TRUE;
  173. }
  174. //--------------------------------------------------------------------------------------------//
  175. // Function to deactivate client impersonation on a request by request basis. This function //
  176. // just uses the m_impersonation flag to determine if impersonation is currently in effect. //
  177. // Input: request //
  178. // Returns: //
  179. //--------------------------------------------------------------------------------------------//
  180. void CProcConClient::UnImpersonate( PCRequest *req ) {
  181. if (m_impersonating && !RevertToSelf()) {
  182. PCLogUnExError( TEXT("PCClient"), TEXT("RevertToSelf") );
  183. }
  184. }
  185. //--------------------------------------------------------------------------------------------//
  186. // Function to process a request in the input buffer and build a response in the output buffer//
  187. // Input: Number of bytes in the input buffer, location to store output buffer length //
  188. // Returns: TRUE if output is to be written, else FALSE //
  189. //--------------------------------------------------------------------------------------------//
  190. BOOL CProcConClient::ProcessRequest( PCULONG32 inLen, PCULONG32 *outLen ) {
  191. PCRequest *req = (PCRequest *) m_inBuf;
  192. PCResponse *rsp = (PCResponse *) m_outBuf;
  193. PrimeResponse( rsp, req );
  194. // Perform cursory checks on incoming request length and contents...
  195. PCULONG32 hdrBytesExpected = sizeof(PCRequest) - sizeof(req->reqData);
  196. if ( inLen < hdrBytesExpected ||
  197. req->reqSignature != SIGNATURE ||
  198. inLen < hdrBytesExpected + req->reqDataLen ) {
  199. return ErrorResponse( PCERROR_INVALID_REQUEST, rsp, outLen );
  200. }
  201. if (!Impersonate( req )) {
  202. PCLogUnExError( TEXT("PCClient"), TEXT("Impersonate") );
  203. return ErrorResponse( GetLastError(), rsp, outLen );
  204. }
  205. ULONG rc = 0;
  206. // Switch on requested data type to process it...
  207. switch ( req->reqType ) {
  208. case PCTYPE_NAMERULE:
  209. rc = DoNameRules( req, rsp, outLen );
  210. break;
  211. case PCTYPE_JOBSUMMARY:
  212. rc = DoJobSummary( req, rsp, outLen );
  213. break;
  214. case PCTYPE_PROCSUMMARY:
  215. rc = DoProcSummary( req, rsp, outLen );
  216. break;
  217. case PCTYPE_PROCDETAIL:
  218. rc = DoProcDetail( req, rsp, outLen );
  219. break;
  220. case PCTYPE_JOBDETAIL:
  221. rc = DoJobDetail( req, rsp, outLen );
  222. break;
  223. case PCTYPE_PROCLIST:
  224. rc = DoProcList( req, rsp, outLen );
  225. break;
  226. case PCTYPE_JOBLIST:
  227. rc = DoJobList( req, rsp, outLen );
  228. break;
  229. case PCTYPE_SERVERINFO:
  230. rc = DoServerInfo( req, rsp, outLen );
  231. break;
  232. case PCTYPE_SERVERPARMS:
  233. rc = DoServerParms( req, rsp, outLen );
  234. break;
  235. case PCTYPE_CONTROL:
  236. rc = DoControl( req, rsp, outLen );
  237. break;
  238. default:
  239. rc = ErrorResponse( PCERROR_INVALID_REQUEST, rsp, outLen );
  240. } // end switch
  241. UnImpersonate( req );
  242. return rc;
  243. }
  244. //--------------------------------------------------------------------------------------------//
  245. // Function to prime a response structure with local data and request data //
  246. // Input: pointers to request and response structures //
  247. //--------------------------------------------------------------------------------------------//
  248. void CProcConClient::PrimeResponse( PCResponse *rsp, PCRequest *req ) {
  249. memset( rsp, 0, sizeof(*rsp) );
  250. rsp->rspReqSignature = SIGNATURE; // sanity check signature
  251. rsp->rspReqSeq = req->reqSeq; // echo of requestor sequence number
  252. rsp->rspReqOp = req->reqOp; // echo of original request operation
  253. rsp->rspReqType = req->reqType; // echo of original request data type
  254. rsp->rspReqVersion = req->reqVersion; // echo of original request data version
  255. rsp->rspVersion = 1; // 1 for base version
  256. rsp->rspTimeStamp = (PCINT32) time( NULL ); // $$ // time stamp associated with the data returned
  257. }
  258. //--------------------------------------------------------------------------------------------//
  259. // Function to build an error response in the output buffer //
  260. // Input: Error code, request pointer, location to store output buffer length //
  261. // Returns: TRUE if output is to be written, else FALSE //
  262. //--------------------------------------------------------------------------------------------//
  263. BOOL CProcConClient::ErrorResponse( PCULONG32 errCode, PCResponse *rsp, PCULONG32 *outLen ) {
  264. rsp->rspResult = (BYTE) (errCode & 0xf0000000 ? PCRESULT_PCERROR: PCRESULT_NTERROR);
  265. rsp->rspError = errCode; // NT or PC error
  266. rsp->rspDataItemCount = 0; // no data returned on error
  267. rsp->rspDataItemLen = 0; // no data returned on error
  268. *outLen = sizeof( *rsp ) - sizeof( rsp->rspData );
  269. return TRUE;
  270. }
  271. //--------------------------------------------------------------------------------------------//
  272. // Function to process a name rules request and build a response in the output buffer //
  273. // Input: Request pointer, location to store output buffer length //
  274. // Returns: TRUE if output is to be written, else FALSE //
  275. //--------------------------------------------------------------------------------------------//
  276. BOOL CProcConClient::DoNameRules( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  277. PCULONG32 err = PCERROR_SUCCESS;
  278. PCNameRule *rule = (PCNameRule *) req->reqData;
  279. rule->matchType = _totupper( rule->matchType );
  280. switch ( req->reqOp ) {
  281. case PCOP_GET:
  282. req->reqFlags |= PCREQFLAG_DOLIST; // just treat as list flag set
  283. break;
  284. case PCOP_ADD:
  285. if ( !PCValidName( rule->procName, ENTRY_COUNT(rule->procName) ) )
  286. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  287. if ( !PCValidMatchType( rule->matchType ) )
  288. return ErrorResponse( PCERROR_INVALID_PARAMETER, rsp, outLen );
  289. err = m_cDB.AddNameRule( rule, req->reqVersion, (PCULONG32) req->reqIndex, req->reqUpdCtr );
  290. break;
  291. case PCOP_REP:
  292. if ( !PCValidName( rule->procName, ENTRY_COUNT(rule->procName) ) )
  293. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  294. if ( !PCValidMatchType( rule->matchType ) )
  295. return ErrorResponse( PCERROR_INVALID_PARAMETER, rsp, outLen );
  296. err = m_cDB.ReplNameRule( rule, req->reqVersion, (PCULONG32) req->reqIndex, req->reqUpdCtr );
  297. break;
  298. case PCOP_DEL:
  299. err = m_cDB.DelNameRule( (PCULONG32) req->reqIndex, req->reqUpdCtr );
  300. break;
  301. case PCOP_ORD:
  302. err = m_cDB.SwapNameRule( (PCULONG32) req->reqIndex, req->reqUpdCtr );
  303. break;
  304. default:
  305. err = PCERROR_INVALID_REQUEST;
  306. break;
  307. } // end switch operation
  308. if ( err != PCERROR_SUCCESS )
  309. return ErrorResponse( err, rsp, outLen );
  310. if ( req->reqFlags & PCREQFLAG_DOLIST ) {
  311. if ( m_cDB.GetNameRules( req->reqFirst, // start from here
  312. (PCNameRule *) rsp->rspData, req->reqCount, // put data here with max count
  313. &rsp->rspDataItemLen, &rsp->rspDataItemCount, // put item len and count here
  314. &rsp->rspUpdCtr ) ) // put updctr here
  315. rsp->rspFlags |= PCRSPFLAG_MOREDATA;
  316. }
  317. *outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
  318. return TRUE;
  319. }
  320. //--------------------------------------------------------------------------------------------//
  321. // Function to handle a process list request and build a response in the output buffer //
  322. // Input: Request pointer, location to store output buffer length //
  323. // Returns: TRUE if output is to be written, else FALSE //
  324. // Note: A process list consists of the names of all processes know to ProcCon: //
  325. // 1) Process names appearing in name rules, //
  326. // 2) Process names defined in ProcCon's database, //
  327. // 3) Any processes currently running and visible to ProcCon. //
  328. //--------------------------------------------------------------------------------------------//
  329. BOOL CProcConClient::DoProcList( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  330. INT32 err = PCERROR_SUCCESS;
  331. PCProcListItem *start = (PCProcListItem *) req->reqData;
  332. switch ( req->reqOp ) {
  333. case PCOP_GET:
  334. if ( !PCValidName( start->procName, ENTRY_COUNT(start->procName), TRUE ) )
  335. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  336. if ( m_cDB.GetProcList( start, (PCULONG32) req->reqIndex, // starting here with these flags
  337. (PCProcListItem *) rsp->rspData, req->reqCount, // put data here with max count
  338. &rsp->rspDataItemLen, &rsp->rspDataItemCount ) ) // put item len and count here
  339. rsp->rspFlags |= PCRSPFLAG_MOREDATA;
  340. break;
  341. case PCOP_KILL:
  342. err = m_cPC.GetPCMgr()->KillProcess( (ULONG_PTR) req->reqIndex, *((TIME_VALUE *) req->reqData) );
  343. break;
  344. default:
  345. err = PCERROR_INVALID_REQUEST;
  346. break;
  347. } // end switch operation
  348. if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
  349. *outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
  350. return TRUE;
  351. }
  352. //--------------------------------------------------------------------------------------------//
  353. // Function to handle a job list request and build a response in the output buffer //
  354. // Input: Request pointer, location to store output buffer length //
  355. // Returns: TRUE if output is to be written, else FALSE //
  356. // Note: A job list consists of the names of all jobs know to ProcCon: //
  357. // 1) Job names appearing in process definitions as "member of group", //
  358. // 2) Job names defined in ProcCon's database, //
  359. // 3) Any jobs currently running and visible to ProcCon. //
  360. //--------------------------------------------------------------------------------------------//
  361. BOOL CProcConClient::DoJobList( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  362. INT32 err = PCERROR_SUCCESS;
  363. PCJobListItem *start = (PCJobListItem *) req->reqData;
  364. switch ( req->reqOp ) {
  365. case PCOP_GET:
  366. if ( !PCValidName( start->jobName, ENTRY_COUNT(start->jobName), TRUE ) )
  367. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  368. if ( m_cDB.GetJobList( start, (PCULONG32) req->reqIndex, // starting here with these flags
  369. (PCJobListItem *) rsp->rspData, req->reqCount, // put data here with max count
  370. &rsp->rspDataItemLen, &rsp->rspDataItemCount ) ) // put item len and count here
  371. rsp->rspFlags |= PCRSPFLAG_MOREDATA;
  372. break;
  373. case PCOP_KILL:
  374. err = m_cPC.GetPCMgr()->KillJob( *((JOB_NAME *) req->reqData) );
  375. break;
  376. default:
  377. err = PCERROR_INVALID_REQUEST;
  378. break;
  379. } // end switch operation
  380. if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
  381. *outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
  382. return TRUE;
  383. }
  384. //--------------------------------------------------------------------------------------------//
  385. // Function to handle a process summary data request and build a response in the output buffer//
  386. // Input: Request pointer, location to store output buffer length //
  387. // Returns: TRUE if output is to be written, else FALSE //
  388. //--------------------------------------------------------------------------------------------//
  389. BOOL CProcConClient::DoProcSummary( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  390. INT32 err = PCERROR_SUCCESS;
  391. PCProcSummary *start = (PCProcSummary *) req->reqData;
  392. switch ( req->reqOp ) {
  393. case PCOP_GET:
  394. if ( !PCValidName( start->procName, ENTRY_COUNT(start->procName), TRUE ) )
  395. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  396. if ( m_cDB.GetProcSummary( start, (PCULONG32) req->reqIndex, // starting here with these flags
  397. (PCProcSummary *) rsp->rspData, req->reqCount, // put data here with max count
  398. &rsp->rspDataItemLen, &rsp->rspDataItemCount ) ) // put item len and count here
  399. rsp->rspFlags |= PCRSPFLAG_MOREDATA;
  400. break;
  401. default:
  402. err = PCERROR_INVALID_REQUEST;
  403. break;
  404. } // end switch operation
  405. if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
  406. *outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
  407. return TRUE;
  408. }
  409. //--------------------------------------------------------------------------------------------//
  410. // Function to handle a job summary data request and build a response in the output buffer //
  411. // Input: Request pointer, location to store output buffer length //
  412. // Returns: TRUE if output is to be written, else FALSE //
  413. //--------------------------------------------------------------------------------------------//
  414. BOOL CProcConClient::DoJobSummary( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  415. INT32 err = PCERROR_SUCCESS;
  416. PCJobSummary *start = (PCJobSummary *) req->reqData;
  417. switch ( req->reqOp ) {
  418. case PCOP_GET:
  419. if ( !PCValidName( start->jobName, ENTRY_COUNT(start->jobName), TRUE ) )
  420. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  421. if ( m_cDB.GetJobSummary( start, (PCULONG32) req->reqIndex, // starting here with these flags
  422. (PCJobSummary *) rsp->rspData, req->reqCount, // put data here with max count
  423. &rsp->rspDataItemLen, &rsp->rspDataItemCount ) ) // put item len and count here
  424. rsp->rspFlags |= PCRSPFLAG_MOREDATA;
  425. break;
  426. default:
  427. err = PCERROR_INVALID_REQUEST;
  428. break;
  429. } // end switch operation
  430. if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
  431. *outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
  432. return TRUE;
  433. }
  434. //--------------------------------------------------------------------------------------------//
  435. // Function to process a process detail data request and build a response in the output buf //
  436. // Input: Request pointer, location to store output buffer and length //
  437. // Returns: TRUE if output is to be written, else FALSE //
  438. //--------------------------------------------------------------------------------------------//
  439. BOOL CProcConClient::DoProcDetail( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  440. INT32 err = PCERROR_SUCCESS;
  441. PCProcDetail *reqDetail = (PCProcDetail *) req->reqData;
  442. PCProcDetail *rspDetail = (PCProcDetail *) rsp->rspData;
  443. if ( !PCValidName( reqDetail->base.procName, ENTRY_COUNT(reqDetail->base.procName) ) )
  444. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  445. switch ( req->reqOp ) {
  446. case PCOP_GET: {
  447. // Set max length of variable data.
  448. int maxVLen = req->maxReply - offsetof(PCProcDetail, vData);
  449. reqDetail->vLength = (PCINT16) max( 0, maxVLen );
  450. // Get detail data and set number (always only 1) and length of returned item.
  451. err = m_cDB.GetProcDetail( reqDetail, rspDetail, req->reqVersion, &rsp->rspUpdCtr );
  452. rsp->rspDataItemCount = 1;
  453. rsp->rspDataItemLen = (PCINT16) (offsetof(PCProcDetail, vData) + rspDetail->vLength);
  454. break;
  455. }
  456. case PCOP_ADD:
  457. if ( !PCValidName( reqDetail->base.memberOfJobName, ENTRY_COUNT(reqDetail->base.memberOfJobName), TRUE ) )
  458. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  459. err = m_cDB.AddProcDetail( reqDetail, req->reqVersion);
  460. if ( err == PCERROR_SUCCESS || err == PCERROR_EXISTS )
  461. GenerateJobDetail( reqDetail );
  462. break;
  463. case PCOP_REP:
  464. if ( !PCValidName( reqDetail->base.memberOfJobName, ENTRY_COUNT(reqDetail->base.memberOfJobName), TRUE ) )
  465. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  466. err = m_cDB.ReplProcDetail( reqDetail, req->reqVersion, req->reqUpdCtr );
  467. if ( err == PCERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND )
  468. GenerateJobDetail( reqDetail );
  469. break;
  470. case PCOP_DEL:
  471. err = m_cDB.DelProcDetail( &reqDetail->base, req->reqVersion);
  472. break;
  473. default:
  474. err = PCERROR_INVALID_REQUEST;
  475. break;
  476. } // end switch operation
  477. if ( err == ERROR_MORE_DATA )
  478. rsp->rspFlags |= PCRSPFLAG_MOREDATA;
  479. else if ( err != PCERROR_SUCCESS )
  480. return ErrorResponse( err, rsp, outLen );
  481. if ( req->reqFlags & PCREQFLAG_DOLIST )
  482. m_cDB.GetProcSummary( (PCProcSummary *) req->reqData, PC_LIST_STARTING_WITH, // starting here
  483. (PCProcSummary *) rsp->rspData, 1, // put data here with count = 1
  484. &rsp->rspDataItemLen, &rsp->rspDataItemCount ); // put item len and count here
  485. *outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
  486. return TRUE;
  487. }
  488. //--------------------------------------------------------------------------------------------//
  489. // Function to generate job detail if needed and it doesn't exist //
  490. // Input: Process detail that may refer to a job //
  491. // Returns: nothing //
  492. //--------------------------------------------------------------------------------------------//
  493. void CProcConClient::GenerateJobDetail( PCProcDetail *reqDetail ) {
  494. if ( *reqDetail->base.memberOfJobName ) {
  495. PCJobDetail jobDetail;
  496. memset( &jobDetail, 0, sizeof(jobDetail) );
  497. memcpy( jobDetail.base.jobName, reqDetail->base.memberOfJobName, sizeof(jobDetail.base.jobName) );
  498. jobDetail.base.mgmtParms.priority = reqDetail->base.mgmtParms.priority;
  499. jobDetail.base.mgmtParms.affinity = reqDetail->base.mgmtParms.affinity;
  500. jobDetail.base.mgmtParms.schedClass = 5;
  501. m_cDB.AddJobDetail( &jobDetail, 1 );
  502. }
  503. }
  504. //--------------------------------------------------------------------------------------------//
  505. // Function to process a job detail request and build a response in the output buffer //
  506. // Input: Request pointer, location to store output buffer length //
  507. // Returns: TRUE if output is to be written, else FALSE //
  508. //--------------------------------------------------------------------------------------------//
  509. BOOL CProcConClient::DoJobDetail( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  510. INT32 err = PCERROR_SUCCESS;
  511. PCJobDetail *reqDetail = (PCJobDetail *) req->reqData;
  512. PCJobDetail *rspDetail = (PCJobDetail *) rsp->rspData;
  513. if ( !PCValidName( reqDetail->base.jobName, ENTRY_COUNT(reqDetail->base.jobName) ) )
  514. return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
  515. switch ( req->reqOp ) {
  516. case PCOP_GET: {
  517. // Set max length of variable data.
  518. int maxVLen = req->maxReply - offsetof(PCJobDetail, vData);
  519. rspDetail->vLength = (PCINT16) max( 0, maxVLen );
  520. // Get detail data and set number (always only 1) and length of returned item.
  521. err = m_cDB.GetJobDetail( reqDetail, rspDetail, req->reqVersion, &rsp->rspUpdCtr );
  522. rsp->rspDataItemCount = 1;
  523. rsp->rspDataItemLen = (PCINT16) (offsetof(PCJobDetail, vData) + rspDetail->vLength);
  524. break;
  525. }
  526. case PCOP_ADD:
  527. err = m_cDB.AddJobDetail( reqDetail, req->reqVersion);
  528. break;
  529. case PCOP_REP:
  530. err = m_cDB.ReplJobDetail( reqDetail, req->reqVersion, req->reqUpdCtr );
  531. break;
  532. case PCOP_DEL:
  533. err = m_cDB.DelJobDetail( &reqDetail->base, req->reqVersion);
  534. break;
  535. default:
  536. err = PCERROR_INVALID_REQUEST;
  537. break;
  538. } // end switch operation
  539. if ( err == ERROR_MORE_DATA )
  540. rsp->rspFlags |= PCRSPFLAG_MOREDATA;
  541. else if ( err != PCERROR_SUCCESS )
  542. return ErrorResponse( err, rsp, outLen );
  543. if ( req->reqFlags & PCREQFLAG_DOLIST )
  544. m_cDB.GetJobSummary( (PCJobSummary *) req->reqData, PC_LIST_STARTING_WITH, // starting here
  545. (PCJobSummary *) rsp->rspData, 1, // put data here with count = 1
  546. &rsp->rspDataItemLen, &rsp->rspDataItemCount ); // put item len and count here
  547. *outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
  548. return TRUE;
  549. }
  550. //--------------------------------------------------------------------------------------------//
  551. // Function to handle a server information request and build a response in the output buffer //
  552. // Input: Request and response pointers, location to store output buffer length //
  553. // Returns: TRUE if output is to be written, else FALSE //
  554. // Note: Server info consists of version info and system parameters. //
  555. //--------------------------------------------------------------------------------------------//
  556. BOOL CProcConClient::DoServerInfo( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  557. INT32 err = PCERROR_SUCCESS;
  558. switch ( req->reqOp ) {
  559. case PCOP_GET:
  560. m_cPC.GetPCSystemInfo( (PCSystemInfo *) rsp->rspData, // put data here
  561. &rsp->rspDataItemLen, &rsp->rspDataItemCount ); // put item len and count here
  562. break;
  563. default:
  564. err = PCERROR_INVALID_REQUEST;
  565. break;
  566. } // end switch operation
  567. if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
  568. *outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
  569. return TRUE;
  570. }
  571. //--------------------------------------------------------------------------------------------//
  572. // Function to handle a server parameter request and build a response in the output buffer //
  573. // Input: Request pointer, location to store output buffer length //
  574. // Returns: TRUE if output is to be written, else FALSE //
  575. // Note: Server info consists of version info and system parameters. //
  576. //--------------------------------------------------------------------------------------------//
  577. BOOL CProcConClient::DoServerParms( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  578. INT32 err = PCERROR_SUCCESS;
  579. switch ( req->reqOp ) {
  580. case PCOP_REP:
  581. err = m_cDB.SetPollDelaySeconds( (PCUINT32) (((PCSystemParms *) req->reqData)->manageIntervalSeconds) );
  582. if ( err == PCERROR_SUCCESS )
  583. err = m_cUser.SetTimeout( (PCUINT32) (((PCSystemParms *) req->reqData)->timeoutValueMs) );
  584. break;
  585. default:
  586. err = PCERROR_INVALID_REQUEST;
  587. break;
  588. } // end switch operation
  589. if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
  590. *outLen = offsetof(PCResponse, rspData);
  591. return TRUE;
  592. }
  593. //--------------------------------------------------------------------------------------------//
  594. // Function to handle a server control request and build a response in the output buffer //
  595. // Input: Request pointer, location to store output buffer length //
  596. // Returns: TRUE if output is to be written, else FALSE //
  597. // Note: Server control consists of a series of bit commands and one piece of data. //
  598. //--------------------------------------------------------------------------------------------//
  599. BOOL CProcConClient::DoControl( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
  600. INT32 err = PCERROR_SUCCESS;
  601. if ( req->reqOp != PCOP_CTL ||
  602. (req->reqIndex & PCCFLAG_SIGNATURE) != PCCFLAG_SIGNATURE ||
  603. req->reqIndex & PCCFLAG_ANTI_SIGNATURE )
  604. err = PCERROR_INVALID_REQUEST;
  605. else {
  606. if ( req->reqIndex & PCCFLAG_STOP_MEDIATOR )
  607. err = m_cPC.StopMediator();
  608. if ( err == PCERROR_SUCCESS && req->reqIndex & PCCFLAG_START_MEDIATOR )
  609. err = m_cPC.StartMediator();
  610. if ( err == PCERROR_SUCCESS && req->reqIndex & PCCFLAG_DELALL_NAME_RULES )
  611. err = m_cDB.DeleteAllNameRules();
  612. if ( err == PCERROR_SUCCESS && req->reqIndex & PCCFLAG_DELALL_PROC_DEFS )
  613. err = m_cDB.DeleteAllProcDefs();
  614. if ( err == PCERROR_SUCCESS && req->reqIndex & PCCFLAG_DELALL_JOB_DEFS )
  615. err = m_cDB.DeleteAllJobDefs();
  616. }
  617. if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
  618. *outLen = offsetof(PCResponse, rspData);
  619. return TRUE;
  620. }
  621. // End of CProcClient.cpp
  622. //============================================================================J McDonald fecit====//